test_blockmem_gridmap_performance.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, the neonavigation authors
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <cstddef>
31 #include <memory>
32 
33 #include <gtest/gtest.h>
34 
36 
37 namespace planner_cspace
38 {
39 TEST(BlockmemGridmap, SpacialAccessPerformance)
40 {
41  constexpr int size[3] =
42  {
43  0x420, 0x420, 0x28
44  };
45  constexpr int pad[3] =
46  {
47  0x204, 0x204, 0x10
48  };
49  constexpr int range = 0x10;
50  constexpr int repeat = 4;
51 
54 
55  using Vec = CyclicVecInt<3, 2>;
56  using ThreeDimArrayFloat = std::array<std::array<std::array<float, size[0]>, size[1]>, size[2]>;
57 
58  // Allocate raw grid in heap memory to avoid stack overflow
59  std::shared_ptr<ThreeDimArrayFloat> array_ptr(new ThreeDimArrayFloat);
60  std::shared_ptr<ThreeDimArrayFloat> array_ret_ptr(new ThreeDimArrayFloat);
61  ThreeDimArrayFloat& array = *array_ptr;
62  ThreeDimArrayFloat& array_ret = *array_ret_ptr;
63 
64  gm.reset(Vec(size[0], size[1], size[2]));
65  gm_ret.reset(Vec(size[0], size[1], size[2]));
66 
67  Vec i;
68  // Generate dataset.
69  for (i[0] = 0; i[0] < size[0]; ++i[0])
70  {
71  for (i[1] = 0; i[1] < size[1]; ++i[1])
72  {
73  for (i[2] = 0; i[2] < size[2]; ++i[2])
74  {
75  gm[i] = i[2] * 0x100 + i[1] * 0x10 + i[0];
76  array[i[2]][i[1]][i[0]] = gm[i];
77  }
78  }
79  }
80  // Check dataset.
81  for (i[0] = pad[0]; i[0] < size[0] - pad[0]; ++i[0])
82  {
83  for (i[1] = pad[1]; i[1] < size[1] - pad[1]; ++i[1])
84  {
85  for (i[2] = pad[2]; i[2] < size[2] - pad[2]; ++i[2])
86  {
87  ASSERT_EQ(gm[i], array[i[2]][i[1]][i[0]]);
88  }
89  }
90  }
91  boost::chrono::duration<float> d0;
92  boost::chrono::duration<float> d1;
93 
94  for (int r = 0; r < repeat; ++r)
95  {
96  // Performance test for BlockMemGridmap.
97  const auto ts0 = boost::chrono::high_resolution_clock::now();
98  for (i[0] = pad[0]; i[0] < size[0] - pad[0]; ++i[0])
99  {
100  for (i[1] = pad[1]; i[1] < size[1] - pad[1]; ++i[1])
101  {
102  for (i[2] = pad[2]; i[2] < size[2] - pad[2]; ++i[2])
103  {
104  Vec j;
105  gm_ret[i] = 0;
106 
107  for (j[0] = -range; j[0] <= range; ++j[0])
108  {
109  for (j[1] = -range; j[1] <= range; ++j[1])
110  {
111  for (j[2] = -range; j[2] <= range; ++j[2])
112  {
113  const Vec ij = i + j;
114  gm_ret[i] += gm[ij];
115  gm[ij]++;
116  }
117  }
118  }
119  }
120  }
121  std::cerr << ".";
122  }
123  std::cerr << std::endl;
124  const auto te0 = boost::chrono::high_resolution_clock::now();
125  d0 += boost::chrono::duration<float>(te0 - ts0);
126 
127  // Performance test for 3D Array.
128  const auto ts1 = boost::chrono::high_resolution_clock::now();
129  for (i[0] = pad[0]; i[0] < size[0] - pad[0]; ++i[0])
130  {
131  for (i[1] = pad[1]; i[1] < size[1] - pad[1]; ++i[1])
132  {
133  for (i[2] = pad[2]; i[2] < size[2] - pad[2]; ++i[2])
134  {
135  Vec j;
136  array_ret[i[2]][i[1]][i[0]] = 0;
137 
138  for (j[0] = -range; j[0] <= range; ++j[0])
139  {
140  for (j[1] = -range; j[1] <= range; ++j[1])
141  {
142  for (j[2] = -range; j[2] <= range; ++j[2])
143  {
144  const Vec ij = i + j;
145  array_ret[i[2]][i[1]][i[0]] += array[ij[2]][ij[1]][ij[0]];
146  array[ij[2]][ij[1]][ij[0]]++;
147  }
148  }
149  }
150  }
151  }
152  std::cerr << ".";
153  }
154  std::cerr << std::endl;
155  const auto te1 = boost::chrono::high_resolution_clock::now();
156  d1 += boost::chrono::duration<float>(te1 - ts1);
157  }
158  std::cout << "BlockMemGridmap<3, 2>: " << d0.count() << std::endl;
159  std::cout << "Array[][][]: " << d1.count() << std::endl;
160 
161  // Check result.
162  for (i[0] = pad[0]; i[0] < size[0] - pad[0]; ++i[0])
163  {
164  for (i[1] = pad[1]; i[1] < size[1] - pad[1]; ++i[1])
165  {
166  for (i[2] = pad[2]; i[2] < size[2] - pad[2]; ++i[2])
167  {
168  ASSERT_EQ(gm_ret[i], array_ret[i[2]][i[1]][i[0]]);
169  }
170  }
171  }
172 
173  // Compare performance.
174  std::cout << "Improvement ratio: " << d1.count() / d0.count() << std::endl;
175  ASSERT_LT(d0, d1);
176 }
177 } // namespace planner_cspace
178 
179 int main(int argc, char** argv)
180 {
181  testing::InitGoogleTest(&argc, argv);
182 
183  return RUN_ALL_TESTS();
184 }
void reset(const CyclicVecInt< DIM, NONCYCLIC > &size)
TEST(BlockmemGridmap, BlockWidth)
int main(int argc, char **argv)


planner_cspace
Author(s): Atsushi Watanabe
autogenerated on Wed May 12 2021 02:20:42