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 <array>
31 #include <cstddef>
32 #include <memory>
33 
34 #include <gtest/gtest.h>
35 
37 
38 namespace planner_cspace
39 {
40 TEST(BlockmemGridmap, SpacialAccessPerformance)
41 {
42  constexpr int size[3] = {0x420, 0x420, 0x28};
43  constexpr int pad[3] = {0x204, 0x204, 0x10};
44  constexpr int range = 0x10;
45  constexpr int repeat = 4;
46 
49 
50  using Vec = CyclicVecInt<3, 2>;
51  using ThreeDimArrayFloat = std::array<std::array<std::array<float, size[0]>, size[1]>, size[2]>;
52 
53  // Allocate raw grid in heap memory to avoid stack overflow
54  std::shared_ptr<ThreeDimArrayFloat> array_ptr(new ThreeDimArrayFloat);
55  std::shared_ptr<ThreeDimArrayFloat> array_ret_ptr(new ThreeDimArrayFloat);
56  ThreeDimArrayFloat& array = *array_ptr;
57  ThreeDimArrayFloat& array_ret = *array_ret_ptr;
58 
59  gm.reset(Vec(size[0], size[1], size[2]));
60  gm_ret.reset(Vec(size[0], size[1], size[2]));
61 
62  Vec i;
63  // Generate dataset.
64  for (i[0] = 0; i[0] < size[0]; ++i[0])
65  {
66  for (i[1] = 0; i[1] < size[1]; ++i[1])
67  {
68  for (i[2] = 0; i[2] < size[2]; ++i[2])
69  {
70  gm[i] = i[2] * 0x100 + i[1] * 0x10 + i[0];
71  array[i[2]][i[1]][i[0]] = gm[i];
72  }
73  }
74  }
75  // Check dataset.
76  for (i[0] = pad[0]; i[0] < size[0] - pad[0]; ++i[0])
77  {
78  for (i[1] = pad[1]; i[1] < size[1] - pad[1]; ++i[1])
79  {
80  for (i[2] = pad[2]; i[2] < size[2] - pad[2]; ++i[2])
81  {
82  ASSERT_EQ(gm[i], array[i[2]][i[1]][i[0]]);
83  }
84  }
85  }
86  boost::chrono::duration<float> d0;
87  boost::chrono::duration<float> d1;
88 
89  for (int r = 0; r < repeat; ++r)
90  {
91  // Performance test for BlockMemGridmap.
92  const auto ts0 = boost::chrono::high_resolution_clock::now();
93  for (i[0] = pad[0]; i[0] < size[0] - pad[0]; ++i[0])
94  {
95  for (i[1] = pad[1]; i[1] < size[1] - pad[1]; ++i[1])
96  {
97  for (i[2] = pad[2]; i[2] < size[2] - pad[2]; ++i[2])
98  {
99  Vec j;
100  gm_ret[i] = 0;
101 
102  for (j[0] = -range; j[0] <= range; ++j[0])
103  {
104  for (j[1] = -range; j[1] <= range; ++j[1])
105  {
106  for (j[2] = -range; j[2] <= range; ++j[2])
107  {
108  const Vec ij = i + j;
109  gm_ret[i] += gm[ij];
110  gm[ij]++;
111  }
112  }
113  }
114  }
115  }
116  std::cerr << ".";
117  }
118  std::cerr << std::endl;
119  const auto te0 = boost::chrono::high_resolution_clock::now();
120  d0 += boost::chrono::duration<float>(te0 - ts0);
121 
122  // Performance test for 3D Array.
123  const auto ts1 = boost::chrono::high_resolution_clock::now();
124  for (i[0] = pad[0]; i[0] < size[0] - pad[0]; ++i[0])
125  {
126  for (i[1] = pad[1]; i[1] < size[1] - pad[1]; ++i[1])
127  {
128  for (i[2] = pad[2]; i[2] < size[2] - pad[2]; ++i[2])
129  {
130  Vec j;
131  array_ret[i[2]][i[1]][i[0]] = 0;
132 
133  for (j[0] = -range; j[0] <= range; ++j[0])
134  {
135  for (j[1] = -range; j[1] <= range; ++j[1])
136  {
137  for (j[2] = -range; j[2] <= range; ++j[2])
138  {
139  const Vec ij = i + j;
140  array_ret[i[2]][i[1]][i[0]] += array[ij[2]][ij[1]][ij[0]];
141  array[ij[2]][ij[1]][ij[0]]++;
142  }
143  }
144  }
145  }
146  }
147  std::cerr << ".";
148  }
149  std::cerr << std::endl;
150  const auto te1 = boost::chrono::high_resolution_clock::now();
151  d1 += boost::chrono::duration<float>(te1 - ts1);
152  }
153  std::cout << "BlockMemGridmap<3, 2>: " << d0.count() << std::endl;
154  std::cout << "Array[][][]: " << d1.count() << std::endl;
155 
156  // Check result.
157  for (i[0] = pad[0]; i[0] < size[0] - pad[0]; ++i[0])
158  {
159  for (i[1] = pad[1]; i[1] < size[1] - pad[1]; ++i[1])
160  {
161  for (i[2] = pad[2]; i[2] < size[2] - pad[2]; ++i[2])
162  {
163  ASSERT_EQ(gm_ret[i], array_ret[i[2]][i[1]][i[0]]);
164  }
165  }
166  }
167 
168  // Compare performance.
169  std::cout << "Improvement ratio: " << d1.count() / d0.count() << std::endl;
170  ASSERT_LT(d0, d1);
171 }
172 } // namespace planner_cspace
173 
174 int main(int argc, char** argv)
175 {
176  testing::InitGoogleTest(&argc, argv);
177 
178  return RUN_ALL_TESTS();
179 }
void reset(const CyclicVecInt< DIM, NONCYCLIC > &size)
TEST(BlockmemGridmap, BlockWidth)
int main(int argc, char **argv)


planner_cspace
Author(s): Atsushi Watanabe
autogenerated on Mon Jul 3 2023 02:39:06