1 /*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <folly/concurrency/CacheLocality.h>
18
19 #include <memory>
20 #include <thread>
21 #include <unordered_map>
22
23 #include <folly/portability/GTest.h>
24 #include <folly/portability/SysResource.h>
25
26 #include <glog/logging.h>
27
28 using namespace folly;
29
30 /// This is the relevant nodes from a production box's sysfs tree. If you
31 /// think this map is ugly you should see the version of this test that
32 /// used a real directory tree. To reduce the chance of testing error
33 /// I haven't tried to remove the common prefix
34 static std::unordered_map<std::string, std::string> fakeSysfsTree = {
35 {"/sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list", "0,17"},
36 {"/sys/devices/system/cpu/cpu0/cache/index0/type", "Data"},
37 {"/sys/devices/system/cpu/cpu0/cache/index1/shared_cpu_list", "0,17"},
38 {"/sys/devices/system/cpu/cpu0/cache/index1/type", "Instruction"},
39 {"/sys/devices/system/cpu/cpu0/cache/index2/shared_cpu_list", "0,17"},
40 {"/sys/devices/system/cpu/cpu0/cache/index2/type", "Unified"},
41 {"/sys/devices/system/cpu/cpu0/cache/index3/shared_cpu_list", "0-8,17-23"},
42 {"/sys/devices/system/cpu/cpu0/cache/index3/type", "Unified"},
43 {"/sys/devices/system/cpu/cpu1/cache/index0/shared_cpu_list", "1,18"},
44 {"/sys/devices/system/cpu/cpu1/cache/index0/type", "Data"},
45 {"/sys/devices/system/cpu/cpu1/cache/index1/shared_cpu_list", "1,18"},
46 {"/sys/devices/system/cpu/cpu1/cache/index1/type", "Instruction"},
47 {"/sys/devices/system/cpu/cpu1/cache/index2/shared_cpu_list", "1,18"},
48 {"/sys/devices/system/cpu/cpu1/cache/index2/type", "Unified"},
49 {"/sys/devices/system/cpu/cpu1/cache/index3/shared_cpu_list", "0-8,17-23"},
50 {"/sys/devices/system/cpu/cpu1/cache/index3/type", "Unified"},
51 {"/sys/devices/system/cpu/cpu2/cache/index0/shared_cpu_list", "2,19"},
52 {"/sys/devices/system/cpu/cpu2/cache/index0/type", "Data"},
53 {"/sys/devices/system/cpu/cpu2/cache/index1/shared_cpu_list", "2,19"},
54 {"/sys/devices/system/cpu/cpu2/cache/index1/type", "Instruction"},
55 {"/sys/devices/system/cpu/cpu2/cache/index2/shared_cpu_list", "2,19"},
56 {"/sys/devices/system/cpu/cpu2/cache/index2/type", "Unified"},
57 {"/sys/devices/system/cpu/cpu2/cache/index3/shared_cpu_list", "0-8,17-23"},
58 {"/sys/devices/system/cpu/cpu2/cache/index3/type", "Unified"},
59 {"/sys/devices/system/cpu/cpu3/cache/index0/shared_cpu_list", "3,20"},
60 {"/sys/devices/system/cpu/cpu3/cache/index0/type", "Data"},
61 {"/sys/devices/system/cpu/cpu3/cache/index1/shared_cpu_list", "3,20"},
62 {"/sys/devices/system/cpu/cpu3/cache/index1/type", "Instruction"},
63 {"/sys/devices/system/cpu/cpu3/cache/index2/shared_cpu_list", "3,20"},
64 {"/sys/devices/system/cpu/cpu3/cache/index2/type", "Unified"},
65 {"/sys/devices/system/cpu/cpu3/cache/index3/shared_cpu_list", "0-8,17-23"},
66 {"/sys/devices/system/cpu/cpu3/cache/index3/type", "Unified"},
67 {"/sys/devices/system/cpu/cpu4/cache/index0/shared_cpu_list", "4,21"},
68 {"/sys/devices/system/cpu/cpu4/cache/index0/type", "Data"},
69 {"/sys/devices/system/cpu/cpu4/cache/index1/shared_cpu_list", "4,21"},
70 {"/sys/devices/system/cpu/cpu4/cache/index1/type", "Instruction"},
71 {"/sys/devices/system/cpu/cpu4/cache/index2/shared_cpu_list", "4,21"},
72 {"/sys/devices/system/cpu/cpu4/cache/index2/type", "Unified"},
73 {"/sys/devices/system/cpu/cpu4/cache/index3/shared_cpu_list", "0-8,17-23"},
74 {"/sys/devices/system/cpu/cpu4/cache/index3/type", "Unified"},
75 {"/sys/devices/system/cpu/cpu5/cache/index0/shared_cpu_list", "5-6"},
76 {"/sys/devices/system/cpu/cpu5/cache/index0/type", "Data"},
77 {"/sys/devices/system/cpu/cpu5/cache/index1/shared_cpu_list", "5-6"},
78 {"/sys/devices/system/cpu/cpu5/cache/index1/type", "Instruction"},
79 {"/sys/devices/system/cpu/cpu5/cache/index2/shared_cpu_list", "5-6"},
80 {"/sys/devices/system/cpu/cpu5/cache/index2/type", "Unified"},
81 {"/sys/devices/system/cpu/cpu5/cache/index3/shared_cpu_list", "0-8,17-23"},
82 {"/sys/devices/system/cpu/cpu5/cache/index3/type", "Unified"},
83 {"/sys/devices/system/cpu/cpu6/cache/index0/shared_cpu_list", "5-6"},
84 {"/sys/devices/system/cpu/cpu6/cache/index0/type", "Data"},
85 {"/sys/devices/system/cpu/cpu6/cache/index1/shared_cpu_list", "5-6"},
86 {"/sys/devices/system/cpu/cpu6/cache/index1/type", "Instruction"},
87 {"/sys/devices/system/cpu/cpu6/cache/index2/shared_cpu_list", "5-6"},
88 {"/sys/devices/system/cpu/cpu6/cache/index2/type", "Unified"},
89 {"/sys/devices/system/cpu/cpu6/cache/index3/shared_cpu_list", "0-8,17-23"},
90 {"/sys/devices/system/cpu/cpu6/cache/index3/type", "Unified"},
91 {"/sys/devices/system/cpu/cpu7/cache/index0/shared_cpu_list", "7,22"},
92 {"/sys/devices/system/cpu/cpu7/cache/index0/type", "Data"},
93 {"/sys/devices/system/cpu/cpu7/cache/index1/shared_cpu_list", "7,22"},
94 {"/sys/devices/system/cpu/cpu7/cache/index1/type", "Instruction"},
95 {"/sys/devices/system/cpu/cpu7/cache/index2/shared_cpu_list", "7,22"},
96 {"/sys/devices/system/cpu/cpu7/cache/index2/type", "Unified"},
97 {"/sys/devices/system/cpu/cpu7/cache/index3/shared_cpu_list", "0-8,17-23"},
98 {"/sys/devices/system/cpu/cpu7/cache/index3/type", "Unified"},
99 {"/sys/devices/system/cpu/cpu8/cache/index0/shared_cpu_list", "8,23"},
100 {"/sys/devices/system/cpu/cpu8/cache/index0/type", "Data"},
101 {"/sys/devices/system/cpu/cpu8/cache/index1/shared_cpu_list", "8,23"},
102 {"/sys/devices/system/cpu/cpu8/cache/index1/type", "Instruction"},
103 {"/sys/devices/system/cpu/cpu8/cache/index2/shared_cpu_list", "8,23"},
104 {"/sys/devices/system/cpu/cpu8/cache/index2/type", "Unified"},
105 {"/sys/devices/system/cpu/cpu8/cache/index3/shared_cpu_list", "0-8,17-23"},
106 {"/sys/devices/system/cpu/cpu8/cache/index3/type", "Unified"},
107 {"/sys/devices/system/cpu/cpu9/cache/index0/shared_cpu_list", "9,24"},
108 {"/sys/devices/system/cpu/cpu9/cache/index0/type", "Data"},
109 {"/sys/devices/system/cpu/cpu9/cache/index1/shared_cpu_list", "9,24"},
110 {"/sys/devices/system/cpu/cpu9/cache/index1/type", "Instruction"},
111 {"/sys/devices/system/cpu/cpu9/cache/index2/shared_cpu_list", "9,24"},
112 {"/sys/devices/system/cpu/cpu9/cache/index2/type", "Unified"},
113 {"/sys/devices/system/cpu/cpu9/cache/index3/shared_cpu_list", "9-16,24-31"},
114 {"/sys/devices/system/cpu/cpu9/cache/index3/type", "Unified"},
115 {"/sys/devices/system/cpu/cpu10/cache/index0/shared_cpu_list", "10,25"},
116 {"/sys/devices/system/cpu/cpu10/cache/index0/type", "Data"},
117 {"/sys/devices/system/cpu/cpu10/cache/index1/shared_cpu_list", "10,25"},
118 {"/sys/devices/system/cpu/cpu10/cache/index1/type", "Instruction"},
119 {"/sys/devices/system/cpu/cpu10/cache/index2/shared_cpu_list", "10,25"},
120 {"/sys/devices/system/cpu/cpu10/cache/index2/type", "Unified"},
121 {"/sys/devices/system/cpu/cpu10/cache/index3/shared_cpu_list",
122 "9-16,24-31"},
123 {"/sys/devices/system/cpu/cpu10/cache/index3/type", "Unified"},
124 {"/sys/devices/system/cpu/cpu11/cache/index0/shared_cpu_list", "11,26"},
125 {"/sys/devices/system/cpu/cpu11/cache/index0/type", "Data"},
126 {"/sys/devices/system/cpu/cpu11/cache/index1/shared_cpu_list", "11,26"},
127 {"/sys/devices/system/cpu/cpu11/cache/index1/type", "Instruction"},
128 {"/sys/devices/system/cpu/cpu11/cache/index2/shared_cpu_list", "11,26"},
129 {"/sys/devices/system/cpu/cpu11/cache/index2/type", "Unified"},
130 {"/sys/devices/system/cpu/cpu11/cache/index3/shared_cpu_list",
131 "9-16,24-31"},
132 {"/sys/devices/system/cpu/cpu11/cache/index3/type", "Unified"},
133 {"/sys/devices/system/cpu/cpu12/cache/index0/shared_cpu_list", "12,27"},
134 {"/sys/devices/system/cpu/cpu12/cache/index0/type", "Data"},
135 {"/sys/devices/system/cpu/cpu12/cache/index1/shared_cpu_list", "12,27"},
136 {"/sys/devices/system/cpu/cpu12/cache/index1/type", "Instruction"},
137 {"/sys/devices/system/cpu/cpu12/cache/index2/shared_cpu_list", "12,27"},
138 {"/sys/devices/system/cpu/cpu12/cache/index2/type", "Unified"},
139 {"/sys/devices/system/cpu/cpu12/cache/index3/shared_cpu_list",
140 "9-16,24-31"},
141 {"/sys/devices/system/cpu/cpu12/cache/index3/type", "Unified"},
142 {"/sys/devices/system/cpu/cpu13/cache/index0/shared_cpu_list", "13,28"},
143 {"/sys/devices/system/cpu/cpu13/cache/index0/type", "Data"},
144 {"/sys/devices/system/cpu/cpu13/cache/index1/shared_cpu_list", "13,28"},
145 {"/sys/devices/system/cpu/cpu13/cache/index1/type", "Instruction"},
146 {"/sys/devices/system/cpu/cpu13/cache/index2/shared_cpu_list", "13,28"},
147 {"/sys/devices/system/cpu/cpu13/cache/index2/type", "Unified"},
148 {"/sys/devices/system/cpu/cpu13/cache/index3/shared_cpu_list",
149 "9-16,24-31"},
150 {"/sys/devices/system/cpu/cpu13/cache/index3/type", "Unified"},
151 {"/sys/devices/system/cpu/cpu14/cache/index0/shared_cpu_list", "14,29"},
152 {"/sys/devices/system/cpu/cpu14/cache/index0/type", "Data"},
153 {"/sys/devices/system/cpu/cpu14/cache/index1/shared_cpu_list", "14,29"},
154 {"/sys/devices/system/cpu/cpu14/cache/index1/type", "Instruction"},
155 {"/sys/devices/system/cpu/cpu14/cache/index2/shared_cpu_list", "14,29"},
156 {"/sys/devices/system/cpu/cpu14/cache/index2/type", "Unified"},
157 {"/sys/devices/system/cpu/cpu14/cache/index3/shared_cpu_list",
158 "9-16,24-31"},
159 {"/sys/devices/system/cpu/cpu14/cache/index3/type", "Unified"},
160 {"/sys/devices/system/cpu/cpu15/cache/index0/shared_cpu_list", "15,30"},
161 {"/sys/devices/system/cpu/cpu15/cache/index0/type", "Data"},
162 {"/sys/devices/system/cpu/cpu15/cache/index1/shared_cpu_list", "15,30"},
163 {"/sys/devices/system/cpu/cpu15/cache/index1/type", "Instruction"},
164 {"/sys/devices/system/cpu/cpu15/cache/index2/shared_cpu_list", "15,30"},
165 {"/sys/devices/system/cpu/cpu15/cache/index2/type", "Unified"},
166 {"/sys/devices/system/cpu/cpu15/cache/index3/shared_cpu_list",
167 "9-16,24-31"},
168 {"/sys/devices/system/cpu/cpu15/cache/index3/type", "Unified"},
169 {"/sys/devices/system/cpu/cpu16/cache/index0/shared_cpu_list", "16,31"},
170 {"/sys/devices/system/cpu/cpu16/cache/index0/type", "Data"},
171 {"/sys/devices/system/cpu/cpu16/cache/index1/shared_cpu_list", "16,31"},
172 {"/sys/devices/system/cpu/cpu16/cache/index1/type", "Instruction"},
173 {"/sys/devices/system/cpu/cpu16/cache/index2/shared_cpu_list", "16,31"},
174 {"/sys/devices/system/cpu/cpu16/cache/index2/type", "Unified"},
175 {"/sys/devices/system/cpu/cpu16/cache/index3/shared_cpu_list",
176 "9-16,24-31"},
177 {"/sys/devices/system/cpu/cpu16/cache/index3/type", "Unified"},
178 {"/sys/devices/system/cpu/cpu17/cache/index0/shared_cpu_list", "0,17"},
179 {"/sys/devices/system/cpu/cpu17/cache/index0/type", "Data"},
180 {"/sys/devices/system/cpu/cpu17/cache/index1/shared_cpu_list", "0,17"},
181 {"/sys/devices/system/cpu/cpu17/cache/index1/type", "Instruction"},
182 {"/sys/devices/system/cpu/cpu17/cache/index2/shared_cpu_list", "0,17"},
183 {"/sys/devices/system/cpu/cpu17/cache/index2/type", "Unified"},
184 {"/sys/devices/system/cpu/cpu17/cache/index3/shared_cpu_list", "0-8,17-23"},
185 {"/sys/devices/system/cpu/cpu17/cache/index3/type", "Unified"},
186 {"/sys/devices/system/cpu/cpu18/cache/index0/shared_cpu_list", "1,18"},
187 {"/sys/devices/system/cpu/cpu18/cache/index0/type", "Data"},
188 {"/sys/devices/system/cpu/cpu18/cache/index1/shared_cpu_list", "1,18"},
189 {"/sys/devices/system/cpu/cpu18/cache/index1/type", "Instruction"},
190 {"/sys/devices/system/cpu/cpu18/cache/index2/shared_cpu_list", "1,18"},
191 {"/sys/devices/system/cpu/cpu18/cache/index2/type", "Unified"},
192 {"/sys/devices/system/cpu/cpu18/cache/index3/shared_cpu_list", "0-8,17-23"},
193 {"/sys/devices/system/cpu/cpu18/cache/index3/type", "Unified"},
194 {"/sys/devices/system/cpu/cpu19/cache/index0/shared_cpu_list", "2,19"},
195 {"/sys/devices/system/cpu/cpu19/cache/index0/type", "Data"},
196 {"/sys/devices/system/cpu/cpu19/cache/index1/shared_cpu_list", "2,19"},
197 {"/sys/devices/system/cpu/cpu19/cache/index1/type", "Instruction"},
198 {"/sys/devices/system/cpu/cpu19/cache/index2/shared_cpu_list", "2,19"},
199 {"/sys/devices/system/cpu/cpu19/cache/index2/type", "Unified"},
200 {"/sys/devices/system/cpu/cpu19/cache/index3/shared_cpu_list", "0-8,17-23"},
201 {"/sys/devices/system/cpu/cpu19/cache/index3/type", "Unified"},
202 {"/sys/devices/system/cpu/cpu20/cache/index0/shared_cpu_list", "3,20"},
203 {"/sys/devices/system/cpu/cpu20/cache/index0/type", "Data"},
204 {"/sys/devices/system/cpu/cpu20/cache/index1/shared_cpu_list", "3,20"},
205 {"/sys/devices/system/cpu/cpu20/cache/index1/type", "Instruction"},
206 {"/sys/devices/system/cpu/cpu20/cache/index2/shared_cpu_list", "3,20"},
207 {"/sys/devices/system/cpu/cpu20/cache/index2/type", "Unified"},
208 {"/sys/devices/system/cpu/cpu20/cache/index3/shared_cpu_list", "0-8,17-23"},
209 {"/sys/devices/system/cpu/cpu20/cache/index3/type", "Unified"},
210 {"/sys/devices/system/cpu/cpu21/cache/index0/shared_cpu_list", "4,21"},
211 {"/sys/devices/system/cpu/cpu21/cache/index0/type", "Data"},
212 {"/sys/devices/system/cpu/cpu21/cache/index1/shared_cpu_list", "4,21"},
213 {"/sys/devices/system/cpu/cpu21/cache/index1/type", "Instruction"},
214 {"/sys/devices/system/cpu/cpu21/cache/index2/shared_cpu_list", "4,21"},
215 {"/sys/devices/system/cpu/cpu21/cache/index2/type", "Unified"},
216 {"/sys/devices/system/cpu/cpu21/cache/index3/shared_cpu_list", "0-8,17-23"},
217 {"/sys/devices/system/cpu/cpu21/cache/index3/type", "Unified"},
218 {"/sys/devices/system/cpu/cpu22/cache/index0/shared_cpu_list", "7,22"},
219 {"/sys/devices/system/cpu/cpu22/cache/index0/type", "Data"},
220 {"/sys/devices/system/cpu/cpu22/cache/index1/shared_cpu_list", "7,22"},
221 {"/sys/devices/system/cpu/cpu22/cache/index1/type", "Instruction"},
222 {"/sys/devices/system/cpu/cpu22/cache/index2/shared_cpu_list", "7,22"},
223 {"/sys/devices/system/cpu/cpu22/cache/index2/type", "Unified"},
224 {"/sys/devices/system/cpu/cpu22/cache/index3/shared_cpu_list", "0-8,17-23"},
225 {"/sys/devices/system/cpu/cpu22/cache/index3/type", "Unified"},
226 {"/sys/devices/system/cpu/cpu23/cache/index0/shared_cpu_list", "8,23"},
227 {"/sys/devices/system/cpu/cpu23/cache/index0/type", "Data"},
228 {"/sys/devices/system/cpu/cpu23/cache/index1/shared_cpu_list", "8,23"},
229 {"/sys/devices/system/cpu/cpu23/cache/index1/type", "Instruction"},
230 {"/sys/devices/system/cpu/cpu23/cache/index2/shared_cpu_list", "8,23"},
231 {"/sys/devices/system/cpu/cpu23/cache/index2/type", "Unified"},
232 {"/sys/devices/system/cpu/cpu23/cache/index3/shared_cpu_list", "0-8,17-23"},
233 {"/sys/devices/system/cpu/cpu23/cache/index3/type", "Unified"},
234 {"/sys/devices/system/cpu/cpu24/cache/index0/shared_cpu_list", "9,24"},
235 {"/sys/devices/system/cpu/cpu24/cache/index0/type", "Data"},
236 {"/sys/devices/system/cpu/cpu24/cache/index1/shared_cpu_list", "9,24"},
237 {"/sys/devices/system/cpu/cpu24/cache/index1/type", "Instruction"},
238 {"/sys/devices/system/cpu/cpu24/cache/index2/shared_cpu_list", "9,24"},
239 {"/sys/devices/system/cpu/cpu24/cache/index2/type", "Unified"},
240 {"/sys/devices/system/cpu/cpu24/cache/index3/shared_cpu_list",
241 "9-16,24-31"},
242 {"/sys/devices/system/cpu/cpu24/cache/index3/type", "Unified"},
243 {"/sys/devices/system/cpu/cpu25/cache/index0/shared_cpu_list", "10,25"},
244 {"/sys/devices/system/cpu/cpu25/cache/index0/type", "Data"},
245 {"/sys/devices/system/cpu/cpu25/cache/index1/shared_cpu_list", "10,25"},
246 {"/sys/devices/system/cpu/cpu25/cache/index1/type", "Instruction"},
247 {"/sys/devices/system/cpu/cpu25/cache/index2/shared_cpu_list", "10,25"},
248 {"/sys/devices/system/cpu/cpu25/cache/index2/type", "Unified"},
249 {"/sys/devices/system/cpu/cpu25/cache/index3/shared_cpu_list",
250 "9-16,24-31"},
251 {"/sys/devices/system/cpu/cpu25/cache/index3/type", "Unified"},
252 {"/sys/devices/system/cpu/cpu26/cache/index0/shared_cpu_list", "11,26"},
253 {"/sys/devices/system/cpu/cpu26/cache/index0/type", "Data"},
254 {"/sys/devices/system/cpu/cpu26/cache/index1/shared_cpu_list", "11,26"},
255 {"/sys/devices/system/cpu/cpu26/cache/index1/type", "Instruction"},
256 {"/sys/devices/system/cpu/cpu26/cache/index2/shared_cpu_list", "11,26"},
257 {"/sys/devices/system/cpu/cpu26/cache/index2/type", "Unified"},
258 {"/sys/devices/system/cpu/cpu26/cache/index3/shared_cpu_list",
259 "9-16,24-31"},
260 {"/sys/devices/system/cpu/cpu26/cache/index3/type", "Unified"},
261 {"/sys/devices/system/cpu/cpu27/cache/index0/shared_cpu_list", "12,27"},
262 {"/sys/devices/system/cpu/cpu27/cache/index0/type", "Data"},
263 {"/sys/devices/system/cpu/cpu27/cache/index1/shared_cpu_list", "12,27"},
264 {"/sys/devices/system/cpu/cpu27/cache/index1/type", "Instruction"},
265 {"/sys/devices/system/cpu/cpu27/cache/index2/shared_cpu_list", "12,27"},
266 {"/sys/devices/system/cpu/cpu27/cache/index2/type", "Unified"},
267 {"/sys/devices/system/cpu/cpu27/cache/index3/shared_cpu_list",
268 "9-16,24-31"},
269 {"/sys/devices/system/cpu/cpu27/cache/index3/type", "Unified"},
270 {"/sys/devices/system/cpu/cpu28/cache/index0/shared_cpu_list", "13,28"},
271 {"/sys/devices/system/cpu/cpu28/cache/index0/type", "Data"},
272 {"/sys/devices/system/cpu/cpu28/cache/index1/shared_cpu_list", "13,28"},
273 {"/sys/devices/system/cpu/cpu28/cache/index1/type", "Instruction"},
274 {"/sys/devices/system/cpu/cpu28/cache/index2/shared_cpu_list", "13,28"},
275 {"/sys/devices/system/cpu/cpu28/cache/index2/type", "Unified"},
276 {"/sys/devices/system/cpu/cpu28/cache/index3/shared_cpu_list",
277 "9-16,24-31"},
278 {"/sys/devices/system/cpu/cpu28/cache/index3/type", "Unified"},
279 {"/sys/devices/system/cpu/cpu29/cache/index0/shared_cpu_list", "14,29"},
280 {"/sys/devices/system/cpu/cpu29/cache/index0/type", "Data"},
281 {"/sys/devices/system/cpu/cpu29/cache/index1/shared_cpu_list", "14,29"},
282 {"/sys/devices/system/cpu/cpu29/cache/index1/type", "Instruction"},
283 {"/sys/devices/system/cpu/cpu29/cache/index2/shared_cpu_list", "14,29"},
284 {"/sys/devices/system/cpu/cpu29/cache/index2/type", "Unified"},
285 {"/sys/devices/system/cpu/cpu29/cache/index3/shared_cpu_list",
286 "9-16,24-31"},
287 {"/sys/devices/system/cpu/cpu29/cache/index3/type", "Unified"},
288 {"/sys/devices/system/cpu/cpu30/cache/index0/shared_cpu_list", "15,30"},
289 {"/sys/devices/system/cpu/cpu30/cache/index0/type", "Data"},
290 {"/sys/devices/system/cpu/cpu30/cache/index1/shared_cpu_list", "15,30"},
291 {"/sys/devices/system/cpu/cpu30/cache/index1/type", "Instruction"},
292 {"/sys/devices/system/cpu/cpu30/cache/index2/shared_cpu_list", "15,30"},
293 {"/sys/devices/system/cpu/cpu30/cache/index2/type", "Unified"},
294 {"/sys/devices/system/cpu/cpu30/cache/index3/shared_cpu_list",
295 "9-16,24-31"},
296 {"/sys/devices/system/cpu/cpu30/cache/index3/type", "Unified"},
297 {"/sys/devices/system/cpu/cpu31/cache/index0/shared_cpu_list", "16,31"},
298 {"/sys/devices/system/cpu/cpu31/cache/index0/type", "Data"},
299 {"/sys/devices/system/cpu/cpu31/cache/index1/shared_cpu_list", "16,31"},
300 {"/sys/devices/system/cpu/cpu31/cache/index1/type", "Instruction"},
301 {"/sys/devices/system/cpu/cpu31/cache/index2/shared_cpu_list", "16,31"},
302 {"/sys/devices/system/cpu/cpu31/cache/index2/type", "Unified"},
303 {"/sys/devices/system/cpu/cpu31/cache/index3/shared_cpu_list",
304 "9-16,24-31"},
305 {"/sys/devices/system/cpu/cpu31/cache/index3/type", "Unified"}};
306
307 /// This is the expected CacheLocality structure for fakeSysfsTree
308 static const CacheLocality nonUniformExampleLocality = {
309 32, {16, 16, 2}, {0, 2, 4, 6, 8, 10, 11, 12, 14, 16, 18,
310 20, 22, 24, 26, 28, 30, 1, 3, 5, 7, 9,
311 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}};
312
TEST(CacheLocality,FakeSysfs)313 TEST(CacheLocality, FakeSysfs) {
314 auto parsed = CacheLocality::readFromSysfsTree([](std::string name) {
315 auto iter = fakeSysfsTree.find(name);
316 return iter == fakeSysfsTree.end() ? std::string() : iter->second;
317 });
318
319 auto& expected = nonUniformExampleLocality;
320 EXPECT_EQ(expected.numCpus, parsed.numCpus);
321 EXPECT_EQ(expected.numCachesByLevel, parsed.numCachesByLevel);
322 EXPECT_EQ(expected.localityIndexByCpu, parsed.localityIndexByCpu);
323 }
324
325 static const std::vector<std::string> fakeProcCpuinfo = {
326 "processor : 0",
327 "vendor_id : GenuineIntel",
328 "cpu family : 6",
329 "model : 79",
330 "model name : Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz",
331 "stepping : 1",
332 "microcode : 0xb00001b",
333 "cpu MHz : 2401.000",
334 "cache size : 35840 KB",
335 "physical id : 0",
336 "siblings : 28",
337 "core id : 0",
338 "cpu cores : 14",
339 "apicid : 0",
340 "initial apicid : 0",
341 "fpu : yes",
342 "fpu_exception : yes",
343 "cpuid level : 20",
344 "wp : yes",
345 "flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch epb cat_l3 cdp_l3 intel_ppin intel_pt tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm cqm rdt_a rdseed adx smap xsaveopt cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts",
346 "bugs :",
347 "bogomips : 4788.90",
348 "clflush size : 64",
349 "cache_alignment : 64",
350 "address sizes : 46 bits physical, 48 bits virtual",
351 "power management:",
352 "",
353 "processor : 1",
354 "cpu family : 6",
355 "cpu MHz : 2401.000",
356 "cache size : 35840 KB",
357 "physical id : 0",
358 "core id : 1",
359 "cpu cores : 14",
360 "cpuid level : 20",
361 "clflush size : 64",
362 "cache_alignment : 64",
363 "power management:",
364 "processor : 2",
365 "cpu family : 6",
366 "cpu MHz : 2401.000",
367 "cache size : 35840 KB",
368 "physical id : 0",
369 "core id : 2",
370 "cpu cores : 14",
371 "cpuid level : 20",
372 "clflush size : 64",
373 "cache_alignment : 64",
374 "power management:",
375 "processor : 3",
376 "cpu family : 6",
377 "cpu MHz : 2401.000",
378 "cache size : 35840 KB",
379 "physical id : 0",
380 "core id : 3",
381 "cpu cores : 14",
382 "cpuid level : 20",
383 "clflush size : 64",
384 "cache_alignment : 64",
385 "power management:",
386 "processor : 4",
387 "cpu family : 6",
388 "cpu MHz : 2401.000",
389 "cache size : 35840 KB",
390 "physical id : 0",
391 "core id : 4",
392 "cpu cores : 14",
393 "cpuid level : 20",
394 "clflush size : 64",
395 "cache_alignment : 64",
396 "power management:",
397 "processor : 5",
398 "cpu family : 6",
399 "cpu MHz : 2401.000",
400 "cache size : 35840 KB",
401 "physical id : 0",
402 "core id : 5",
403 "cpu cores : 14",
404 "cpuid level : 20",
405 "clflush size : 64",
406 "cache_alignment : 64",
407 "power management:",
408 "processor : 6",
409 "cpu family : 6",
410 "cpu MHz : 2401.000",
411 "cache size : 35840 KB",
412 "physical id : 0",
413 "core id : 6",
414 "cpu cores : 14",
415 "cpuid level : 20",
416 "clflush size : 64",
417 "cache_alignment : 64",
418 "power management:",
419 "processor : 7",
420 "cpu family : 6",
421 "cpu MHz : 2401.000",
422 "cache size : 35840 KB",
423 "physical id : 0",
424 "core id : 8",
425 "cpu cores : 14",
426 "cpuid level : 20",
427 "clflush size : 64",
428 "cache_alignment : 64",
429 "power management:",
430 "processor : 8",
431 "cpu family : 6",
432 "cpu MHz : 2401.000",
433 "cache size : 35840 KB",
434 "physical id : 0",
435 "core id : 9",
436 "cpu cores : 14",
437 "cpuid level : 20",
438 "clflush size : 64",
439 "cache_alignment : 64",
440 "power management:",
441 "processor : 9",
442 "cpu family : 6",
443 "cpu MHz : 2401.000",
444 "cache size : 35840 KB",
445 "physical id : 0",
446 "core id : 10",
447 "cpu cores : 14",
448 "cpuid level : 20",
449 "clflush size : 64",
450 "cache_alignment : 64",
451 "power management:",
452 "processor : 10",
453 "cpu family : 6",
454 "cpu MHz : 2401.000",
455 "cache size : 35840 KB",
456 "physical id : 0",
457 "core id : 11",
458 "cpu cores : 14",
459 "cpuid level : 20",
460 "clflush size : 64",
461 "cache_alignment : 64",
462 "power management:",
463 "processor : 11",
464 "cpu family : 6",
465 "cpu MHz : 2401.000",
466 "cache size : 35840 KB",
467 "physical id : 0",
468 "core id : 12",
469 "cpu cores : 14",
470 "cpuid level : 20",
471 "clflush size : 64",
472 "cache_alignment : 64",
473 "power management:",
474 "processor : 12",
475 "cpu family : 6",
476 "cpu MHz : 2401.000",
477 "cache size : 35840 KB",
478 "physical id : 0",
479 "core id : 13",
480 "cpu cores : 14",
481 "cpuid level : 20",
482 "clflush size : 64",
483 "cache_alignment : 64",
484 "power management:",
485 "processor : 13",
486 "cpu family : 6",
487 "cpu MHz : 2401.000",
488 "cache size : 35840 KB",
489 "physical id : 0",
490 "core id : 14",
491 "cpu cores : 14",
492 "cpuid level : 20",
493 "clflush size : 64",
494 "cache_alignment : 64",
495 "power management:",
496 "processor : 14",
497 "cpu family : 6",
498 "cpu MHz : 2401.000",
499 "cache size : 35840 KB",
500 "physical id : 1",
501 "core id : 0",
502 "cpu cores : 14",
503 "cpuid level : 20",
504 "clflush size : 64",
505 "cache_alignment : 64",
506 "power management:",
507 "processor : 15",
508 "cpu family : 6",
509 "cpu MHz : 2401.000",
510 "cache size : 35840 KB",
511 "physical id : 1",
512 "core id : 1",
513 "cpu cores : 14",
514 "cpuid level : 20",
515 "clflush size : 64",
516 "cache_alignment : 64",
517 "power management:",
518 "processor : 16",
519 "cpu family : 6",
520 "cpu MHz : 2401.000",
521 "cache size : 35840 KB",
522 "physical id : 1",
523 "core id : 2",
524 "cpu cores : 14",
525 "cpuid level : 20",
526 "clflush size : 64",
527 "cache_alignment : 64",
528 "power management:",
529 "processor : 17",
530 "cpu family : 6",
531 "cpu MHz : 2401.000",
532 "cache size : 35840 KB",
533 "physical id : 1",
534 "core id : 3",
535 "cpu cores : 14",
536 "cpuid level : 20",
537 "clflush size : 64",
538 "cache_alignment : 64",
539 "power management:",
540 "processor : 18",
541 "cpu family : 6",
542 "cpu MHz : 2401.000",
543 "cache size : 35840 KB",
544 "physical id : 1",
545 "core id : 4",
546 "cpu cores : 14",
547 "cpuid level : 20",
548 "clflush size : 64",
549 "cache_alignment : 64",
550 "power management:",
551 "processor : 19",
552 "cpu family : 6",
553 "cpu MHz : 2401.000",
554 "cache size : 35840 KB",
555 "physical id : 1",
556 "core id : 5",
557 "cpu cores : 14",
558 "cpuid level : 20",
559 "clflush size : 64",
560 "cache_alignment : 64",
561 "power management:",
562 "processor : 20",
563 "cpu family : 6",
564 "cpu MHz : 2401.000",
565 "cache size : 35840 KB",
566 "physical id : 1",
567 "core id : 6",
568 "cpu cores : 14",
569 "cpuid level : 20",
570 "clflush size : 64",
571 "cache_alignment : 64",
572 "power management:",
573 "processor : 21",
574 "cpu family : 6",
575 "cpu MHz : 2401.000",
576 "cache size : 35840 KB",
577 "physical id : 1",
578 "core id : 8",
579 "cpu cores : 14",
580 "cpuid level : 20",
581 "clflush size : 64",
582 "cache_alignment : 64",
583 "power management:",
584 "processor : 22",
585 "cpu family : 6",
586 "cpu MHz : 2401.000",
587 "cache size : 35840 KB",
588 "physical id : 1",
589 "core id : 9",
590 "cpu cores : 14",
591 "cpuid level : 20",
592 "clflush size : 64",
593 "cache_alignment : 64",
594 "power management:",
595 "processor : 23",
596 "cpu family : 6",
597 "cpu MHz : 2401.000",
598 "cache size : 35840 KB",
599 "physical id : 1",
600 "core id : 10",
601 "cpu cores : 14",
602 "cpuid level : 20",
603 "clflush size : 64",
604 "cache_alignment : 64",
605 "power management:",
606 "processor : 24",
607 "cpu family : 6",
608 "cpu MHz : 2401.000",
609 "cache size : 35840 KB",
610 "physical id : 1",
611 "core id : 11",
612 "cpu cores : 14",
613 "cpuid level : 20",
614 "clflush size : 64",
615 "cache_alignment : 64",
616 "power management:",
617 "processor : 25",
618 "cpu family : 6",
619 "cpu MHz : 2401.000",
620 "cache size : 35840 KB",
621 "physical id : 1",
622 "core id : 12",
623 "cpu cores : 14",
624 "cpuid level : 20",
625 "clflush size : 64",
626 "cache_alignment : 64",
627 "power management:",
628 "processor : 26",
629 "cpu family : 6",
630 "cpu MHz : 2401.000",
631 "cache size : 35840 KB",
632 "physical id : 1",
633 "core id : 13",
634 "cpu cores : 14",
635 "cpuid level : 20",
636 "clflush size : 64",
637 "cache_alignment : 64",
638 "power management:",
639 "processor : 27",
640 "cpu family : 6",
641 "cpu MHz : 2401.000",
642 "cache size : 35840 KB",
643 "physical id : 1",
644 "core id : 14",
645 "cpu cores : 14",
646 "cpuid level : 20",
647 "clflush size : 64",
648 "cache_alignment : 64",
649 "power management:",
650 "processor : 28",
651 "cpu family : 6",
652 "cpu MHz : 2401.000",
653 "cache size : 35840 KB",
654 "physical id : 0",
655 "core id : 0",
656 "cpu cores : 14",
657 "cpuid level : 20",
658 "clflush size : 64",
659 "cache_alignment : 64",
660 "power management:",
661 "processor : 29",
662 "cpu family : 6",
663 "cpu MHz : 2401.000",
664 "cache size : 35840 KB",
665 "physical id : 0",
666 "core id : 1",
667 "cpu cores : 14",
668 "cpuid level : 20",
669 "clflush size : 64",
670 "cache_alignment : 64",
671 "power management:",
672 "processor : 30",
673 "cpu family : 6",
674 "cpu MHz : 2401.000",
675 "cache size : 35840 KB",
676 "physical id : 0",
677 "core id : 2",
678 "cpu cores : 14",
679 "cpuid level : 20",
680 "clflush size : 64",
681 "cache_alignment : 64",
682 "power management:",
683 "processor : 31",
684 "cpu family : 6",
685 "cpu MHz : 2401.000",
686 "cache size : 35840 KB",
687 "physical id : 0",
688 "core id : 3",
689 "cpu cores : 14",
690 "cpuid level : 20",
691 "clflush size : 64",
692 "cache_alignment : 64",
693 "power management:",
694 "processor : 32",
695 "cpu family : 6",
696 "cpu MHz : 2401.000",
697 "cache size : 35840 KB",
698 "physical id : 0",
699 "core id : 4",
700 "cpu cores : 14",
701 "cpuid level : 20",
702 "clflush size : 64",
703 "cache_alignment : 64",
704 "power management:",
705 "processor : 33",
706 "cpu family : 6",
707 "cpu MHz : 2401.000",
708 "cache size : 35840 KB",
709 "physical id : 0",
710 "core id : 5",
711 "cpu cores : 14",
712 "cpuid level : 20",
713 "clflush size : 64",
714 "cache_alignment : 64",
715 "power management:",
716 "processor : 34",
717 "cpu family : 6",
718 "cpu MHz : 2401.000",
719 "cache size : 35840 KB",
720 "physical id : 0",
721 "core id : 6",
722 "cpu cores : 14",
723 "cpuid level : 20",
724 "clflush size : 64",
725 "cache_alignment : 64",
726 "power management:",
727 "processor : 35",
728 "cpu family : 6",
729 "cpu MHz : 2401.000",
730 "cache size : 35840 KB",
731 "physical id : 0",
732 "core id : 8",
733 "cpu cores : 14",
734 "cpuid level : 20",
735 "clflush size : 64",
736 "cache_alignment : 64",
737 "power management:",
738 "processor : 36",
739 "cpu family : 6",
740 "cpu MHz : 2401.000",
741 "cache size : 35840 KB",
742 "physical id : 0",
743 "core id : 9",
744 "cpu cores : 14",
745 "cpuid level : 20",
746 "clflush size : 64",
747 "cache_alignment : 64",
748 "power management:",
749 "processor : 37",
750 "cpu family : 6",
751 "cpu MHz : 2401.000",
752 "cache size : 35840 KB",
753 "physical id : 0",
754 "core id : 10",
755 "cpu cores : 14",
756 "cpuid level : 20",
757 "clflush size : 64",
758 "cache_alignment : 64",
759 "power management:",
760 "processor : 38",
761 "cpu family : 6",
762 "cpu MHz : 2401.000",
763 "cache size : 35840 KB",
764 "physical id : 0",
765 "core id : 11",
766 "cpu cores : 14",
767 "cpuid level : 20",
768 "clflush size : 64",
769 "cache_alignment : 64",
770 "power management:",
771 "processor : 39",
772 "cpu family : 6",
773 "cpu MHz : 2401.000",
774 "cache size : 35840 KB",
775 "physical id : 0",
776 "core id : 12",
777 "cpu cores : 14",
778 "cpuid level : 20",
779 "clflush size : 64",
780 "cache_alignment : 64",
781 "power management:",
782 "processor : 40",
783 "cpu family : 6",
784 "cpu MHz : 2401.000",
785 "cache size : 35840 KB",
786 "physical id : 0",
787 "core id : 13",
788 "cpu cores : 14",
789 "cpuid level : 20",
790 "clflush size : 64",
791 "cache_alignment : 64",
792 "power management:",
793 "processor : 41",
794 "cpu family : 6",
795 "cpu MHz : 2401.000",
796 "cache size : 35840 KB",
797 "physical id : 0",
798 "core id : 14",
799 "cpu cores : 14",
800 "cpuid level : 20",
801 "clflush size : 64",
802 "cache_alignment : 64",
803 "power management:",
804 "processor : 42",
805 "cpu family : 6",
806 "cpu MHz : 2401.000",
807 "cache size : 35840 KB",
808 "physical id : 1",
809 "core id : 0",
810 "cpu cores : 14",
811 "cpuid level : 20",
812 "clflush size : 64",
813 "cache_alignment : 64",
814 "power management:",
815 "processor : 43",
816 "cpu family : 6",
817 "cpu MHz : 2401.000",
818 "cache size : 35840 KB",
819 "physical id : 1",
820 "core id : 1",
821 "cpu cores : 14",
822 "cpuid level : 20",
823 "clflush size : 64",
824 "cache_alignment : 64",
825 "power management:",
826 "processor : 44",
827 "cpu family : 6",
828 "cpu MHz : 2401.000",
829 "cache size : 35840 KB",
830 "physical id : 1",
831 "core id : 2",
832 "cpu cores : 14",
833 "cpuid level : 20",
834 "clflush size : 64",
835 "cache_alignment : 64",
836 "power management:",
837 "processor : 45",
838 "cpu family : 6",
839 "cpu MHz : 2401.000",
840 "cache size : 35840 KB",
841 "physical id : 1",
842 "core id : 3",
843 "cpu cores : 14",
844 "cpuid level : 20",
845 "clflush size : 64",
846 "cache_alignment : 64",
847 "power management:",
848 "processor : 46",
849 "cpu family : 6",
850 "cpu MHz : 2401.000",
851 "cache size : 35840 KB",
852 "physical id : 1",
853 "core id : 4",
854 "cpu cores : 14",
855 "cpuid level : 20",
856 "clflush size : 64",
857 "cache_alignment : 64",
858 "power management:",
859 "processor : 47",
860 "cpu family : 6",
861 "cpu MHz : 2401.000",
862 "cache size : 35840 KB",
863 "physical id : 1",
864 "core id : 5",
865 "cpu cores : 14",
866 "cpuid level : 20",
867 "clflush size : 64",
868 "cache_alignment : 64",
869 "power management:",
870 "processor : 48",
871 "cpu family : 6",
872 "cpu MHz : 2401.000",
873 "cache size : 35840 KB",
874 "physical id : 1",
875 "core id : 6",
876 "cpu cores : 14",
877 "cpuid level : 20",
878 "clflush size : 64",
879 "cache_alignment : 64",
880 "power management:",
881 "processor : 49",
882 "cpu family : 6",
883 "cpu MHz : 2401.000",
884 "cache size : 35840 KB",
885 "physical id : 1",
886 "core id : 8",
887 "cpu cores : 14",
888 "cpuid level : 20",
889 "clflush size : 64",
890 "cache_alignment : 64",
891 "power management:",
892 "processor : 50",
893 "cpu family : 6",
894 "cpu MHz : 2401.000",
895 "cache size : 35840 KB",
896 "physical id : 1",
897 "core id : 9",
898 "cpu cores : 14",
899 "cpuid level : 20",
900 "clflush size : 64",
901 "cache_alignment : 64",
902 "power management:",
903 "processor : 51",
904 "cpu family : 6",
905 "cpu MHz : 2401.000",
906 "cache size : 35840 KB",
907 "physical id : 1",
908 "core id : 10",
909 "cpu cores : 14",
910 "cpuid level : 20",
911 "clflush size : 64",
912 "cache_alignment : 64",
913 "power management:",
914 "processor : 52",
915 "cpu family : 6",
916 "cpu MHz : 2401.000",
917 "cache size : 35840 KB",
918 "physical id : 1",
919 "core id : 11",
920 "cpu cores : 14",
921 "cpuid level : 20",
922 "clflush size : 64",
923 "cache_alignment : 64",
924 "power management:",
925 "processor : 53",
926 "cpu family : 6",
927 "cpu MHz : 2401.000",
928 "cache size : 35840 KB",
929 "physical id : 1",
930 "core id : 12",
931 "cpu cores : 14",
932 "cpuid level : 20",
933 "clflush size : 64",
934 "cache_alignment : 64",
935 "power management:",
936 "processor : 54",
937 "cpu family : 6",
938 "cpu MHz : 2401.000",
939 "cache size : 35840 KB",
940 "physical id : 1",
941 "core id : 13",
942 "cpu cores : 14",
943 "cpuid level : 20",
944 "clflush size : 64",
945 "cache_alignment : 64",
946 "power management:",
947 "processor : 55",
948 "cpu family : 6",
949 "cpu MHz : 2401.000",
950 "cache size : 35840 KB",
951 "physical id : 1",
952 "core id : 14",
953 "cpu cores : 14",
954 "cpuid level : 20",
955 "clflush size : 64",
956 "cache_alignment : 64",
957 "power management:",
958 };
959
960 /// This is the expected CacheLocality structure for fakeProcCpuinfo
961 static const CacheLocality fakeProcCpuinfoLocality = {
962 56, {28, 28, 2}, {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26,
963 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
964 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27,
965 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55}};
966
TEST(CacheLocality,ProcCpu)967 TEST(CacheLocality, ProcCpu) {
968 auto parsed = CacheLocality::readFromProcCpuinfoLines(fakeProcCpuinfo);
969 auto& expected = fakeProcCpuinfoLocality;
970 EXPECT_EQ(expected.numCpus, parsed.numCpus);
971 EXPECT_EQ(expected.numCachesByLevel, parsed.numCachesByLevel);
972 EXPECT_EQ(expected.localityIndexByCpu, parsed.localityIndexByCpu);
973 }
974
TEST(CacheLocality,LinuxActual)975 TEST(CacheLocality, LinuxActual) {
976 if (!kIsLinux) {
977 return;
978 }
979
980 auto parsed1 = CacheLocality::readFromProcCpuinfo();
981 EXPECT_EQ(parsed1.numCpus, std::thread::hardware_concurrency());
982
983 auto parsed2 = CacheLocality::readFromSysfs();
984 EXPECT_EQ(parsed2.numCpus, std::thread::hardware_concurrency());
985
986 EXPECT_EQ(parsed1.localityIndexByCpu, parsed2.localityIndexByCpu);
987 }
988
TEST(CacheLocality,LogSystem)989 TEST(CacheLocality, LogSystem) {
990 auto& sys = CacheLocality::system<>();
991 LOG(INFO) << "numCpus= " << sys.numCpus;
992 LOG(INFO) << "numCachesByLevel= ";
993 for (std::size_t i = 0; i < sys.numCachesByLevel.size(); ++i) {
994 LOG(INFO) << " [" << i << "]= " << sys.numCachesByLevel[i];
995 }
996 LOG(INFO) << "localityIndexByCpu= ";
997 for (std::size_t i = 0; i < sys.localityIndexByCpu.size(); ++i) {
998 LOG(INFO) << " [" << i << "]= " << sys.localityIndexByCpu[i];
999 }
1000 }
1001
1002 #ifdef RUSAGE_THREAD
micros(struct timeval & tv)1003 static uint64_t micros(struct timeval& tv) {
1004 return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
1005 }
1006
1007 template <typename F>
logRusageFor(std::string name,F func)1008 static void logRusageFor(std::string name, F func) {
1009 struct rusage before;
1010 getrusage(RUSAGE_THREAD, &before);
1011 auto beforeNow = std::chrono::steady_clock::now();
1012 func();
1013 auto afterNow = std::chrono::steady_clock::now();
1014 struct rusage after;
1015 getrusage(RUSAGE_THREAD, &after);
1016 LOG(INFO) << name << ": real: "
1017 << std::chrono::duration_cast<std::chrono::microseconds>(
1018 afterNow - beforeNow)
1019 .count()
1020 << " usec, user: "
1021 << (micros(after.ru_utime) - micros(before.ru_utime))
1022 << " usec, sys: "
1023 << (micros(after.ru_stime) - micros(before.ru_stime)) << " usec";
1024 }
1025
TEST(CacheLocality,BenchmarkProcCpuinfo)1026 TEST(CacheLocality, BenchmarkProcCpuinfo) {
1027 logRusageFor("readFromProcCpuinfo", CacheLocality::readFromProcCpuinfo);
1028 }
1029
TEST(CacheLocality,BenchmarkSysfs)1030 TEST(CacheLocality, BenchmarkSysfs) {
1031 logRusageFor("readFromSysfs", CacheLocality::readFromSysfs);
1032 }
1033 #endif
1034
1035 #if defined(FOLLY_HAVE_LINUX_VDSO) && !defined(FOLLY_SANITIZE_MEMORY)
TEST(Getcpu,VdsoGetcpu)1036 TEST(Getcpu, VdsoGetcpu) {
1037 unsigned cpu;
1038 Getcpu::resolveVdsoFunc()(&cpu, nullptr, nullptr);
1039
1040 EXPECT_TRUE(cpu < CPU_SETSIZE);
1041 }
1042 #endif
1043
TEST(ThreadId,SimpleTls)1044 TEST(ThreadId, SimpleTls) {
1045 unsigned cpu = 0;
1046 auto rv =
1047 folly::FallbackGetcpu<SequentialThreadId>::getcpu(&cpu, nullptr, nullptr);
1048 EXPECT_EQ(rv, 0);
1049 EXPECT_TRUE(cpu > 0);
1050 unsigned again;
1051 folly::FallbackGetcpu<SequentialThreadId>::getcpu(&again, nullptr, nullptr);
1052 EXPECT_EQ(cpu, again);
1053 }
1054
TEST(ThreadId,SimplePthread)1055 TEST(ThreadId, SimplePthread) {
1056 unsigned cpu = 0;
1057 auto rv =
1058 folly::FallbackGetcpu<HashingThreadId>::getcpu(&cpu, nullptr, nullptr);
1059 EXPECT_EQ(rv, 0);
1060 EXPECT_TRUE(cpu > 0);
1061 unsigned again;
1062 folly::FallbackGetcpu<HashingThreadId>::getcpu(&again, nullptr, nullptr);
1063 EXPECT_EQ(cpu, again);
1064 }
1065
1066 static thread_local unsigned testingCpu = 0;
1067
testingGetcpu(unsigned * cpu,unsigned * node,void *)1068 static int testingGetcpu(unsigned* cpu, unsigned* node, void* /* unused */) {
1069 if (cpu != nullptr) {
1070 *cpu = testingCpu;
1071 }
1072 if (node != nullptr) {
1073 *node = testingCpu;
1074 }
1075 return 0;
1076 }
1077
TEST(AccessSpreader,Simple)1078 TEST(AccessSpreader, Simple) {
1079 for (size_t s = 1; s < 200; ++s) {
1080 EXPECT_LT(AccessSpreader<>::current(s), s);
1081 }
1082 }
1083
TEST(AccessSpreader,SimpleCached)1084 TEST(AccessSpreader, SimpleCached) {
1085 for (size_t s = 1; s < 200; ++s) {
1086 EXPECT_LT(AccessSpreader<>::cachedCurrent(s), s);
1087 }
1088 }
1089
TEST(AccessSpreader,ConcurrentAccessCached)1090 TEST(AccessSpreader, ConcurrentAccessCached) {
1091 std::vector<std::thread> threads;
1092 for (size_t i = 0; i < 4; ++i) {
1093 threads.emplace_back([]() {
1094 for (size_t s : {16, 32, 64}) {
1095 for (size_t j = 1; j < 200; ++j) {
1096 EXPECT_LT(AccessSpreader<>::cachedCurrent(s), s);
1097 EXPECT_LT(AccessSpreader<>::cachedCurrent(s), s);
1098 }
1099 std::this_thread::yield();
1100 }
1101 });
1102 }
1103 for (auto& thread : threads) {
1104 thread.join();
1105 }
1106 }
1107
1108 #define DECLARE_SPREADER_TAG(tag, locality, func) \
1109 namespace { \
1110 template <typename dummy> \
1111 struct tag {}; \
1112 } \
1113 namespace folly { \
1114 template <> \
1115 const CacheLocality& CacheLocality::system<tag>() { \
1116 static auto* inst = new CacheLocality(locality); \
1117 return *inst; \
1118 } \
1119 template <> \
1120 Getcpu::Func AccessSpreader<tag>::pickGetcpuFunc() { \
1121 return func; \
1122 } \
1123 template struct AccessSpreader<tag>; \
1124 }
1125
1126 DECLARE_SPREADER_TAG(ManualTag, CacheLocality::uniform(16), testingGetcpu)
1127
TEST(AccessSpreader,Wrapping)1128 TEST(AccessSpreader, Wrapping) {
1129 // this test won't pass unless locality.numCpus divides kMaxCpus
1130 auto numCpus = CacheLocality::system<ManualTag>().numCpus;
1131 EXPECT_EQ(0, 128 % numCpus);
1132 for (size_t s = 1; s < 200; ++s) {
1133 for (size_t c = 0; c < 400; ++c) {
1134 testingCpu = c;
1135 auto observed = AccessSpreader<ManualTag>::current(s);
1136 testingCpu = c % numCpus;
1137 auto expected = AccessSpreader<ManualTag>::current(s);
1138 EXPECT_EQ(expected, observed)
1139 << "numCpus=" << numCpus << ", s=" << s << ", c=" << c;
1140 EXPECT_LE(observed, AccessSpreader<ManualTag>::maxStripeValue());
1141 }
1142 }
1143 }
1144
TEST(CoreRawAllocator,Basic)1145 TEST(CoreRawAllocator, Basic) {
1146 CoreRawAllocator<32> alloc;
1147 auto& a = alloc.get(0);
1148 auto res = a.allocate(8);
1149 memset(res, 0, 8);
1150 a.deallocate(res);
1151 res = a.allocate(8);
1152 EXPECT_TRUE((intptr_t)res % 8 == 0); // check alignment
1153 memset(res, 0, 8);
1154 a.deallocate(res);
1155 res = a.allocate(12);
1156 EXPECT_TRUE((intptr_t)res % 16 == 0); // check alignment
1157 memset(res, 0, 12);
1158 a.deallocate(res);
1159 res = a.allocate(257);
1160 memset(res, 0, 257);
1161 a.deallocate(res);
1162
1163 std::vector<void*> mems;
1164 for (int i = 0; i < 10000; i++) {
1165 mems.push_back(a.allocate(1));
1166 }
1167 for (auto& mem : mems) {
1168 a.deallocate(mem);
1169 }
1170 mems.clear();
1171 }
1172