Rev 169 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 169 | Rev 185 | ||
---|---|---|---|
Line 4... | Line 4... | ||
4 | Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad |
4 | Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad |
5 | Copyright (C) 2015- |
5 | Copyright (C) 2015-2019 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad |
6 | 6 | ||
7 | Stockfish is free software: you can redistribute it and/or modify |
7 | Stockfish is free software: you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation, either version 3 of the License, or |
9 | the Free Software Foundation, either version 3 of the License, or |
10 | (at your option) any later version. |
10 | (at your option) any later version. |
Line 21... | Line 21... | ||
21 | #ifdef _WIN32 |
21 | #ifdef _WIN32 |
22 | #if _WIN32_WINNT < 0x0601 |
22 | #if _WIN32_WINNT < 0x0601 |
23 | #undef _WIN32_WINNT |
23 | #undef _WIN32_WINNT |
24 | #define _WIN32_WINNT 0x0601 // Force to include needed API prototypes |
24 | #define _WIN32_WINNT 0x0601 // Force to include needed API prototypes |
25 | #endif |
25 | #endif |
- | 26 | ||
- | 27 | #ifndef NOMINMAX |
|
- | 28 | #define NOMINMAX |
|
- | 29 | #endif |
|
- | 30 | ||
26 | #include <windows.h> |
31 | #include <windows.h> |
27 | // The needed Windows API for processor groups could be missed from old Windows |
32 | // The needed Windows API for processor groups could be missed from old Windows |
28 | // versions, so instead of calling them directly (forcing the linker to resolve |
33 | // versions, so instead of calling them directly (forcing the linker to resolve |
29 | // the calls at compile time), try to load them at runtime. To do this we need |
34 | // the calls at compile time), try to load them at runtime. To do this we need |
30 | // first to define the corresponding function pointers. |
35 | // first to define the corresponding function pointers. |
Line 49... | Line 54... | ||
49 | 54 | ||
50 | namespace { |
55 | namespace { |
51 | 56 | ||
52 | /// Version number. If Version is left empty, then compile date in the format |
57 | /// Version number. If Version is left empty, then compile date in the format |
53 | /// DD-MM-YY and show in engine_info. |
58 | /// DD-MM-YY and show in engine_info. |
54 | const string Version = " |
59 | const string Version = "10"; |
55 | 60 | ||
56 | /// Our fancy logging facility. The trick here is to replace cin.rdbuf() and |
61 | /// Our fancy logging facility. The trick here is to replace cin.rdbuf() and |
57 | /// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We |
62 | /// cout.rdbuf() with two Tie objects that tie cin and cout to a file stream. We |
58 | /// can toggle the logging of std::cout and std:cin at runtime whilst preserving |
63 | /// can toggle the logging of std::cout and std:cin at runtime whilst preserving |
59 | /// usual I/O functionality, all without changing a single line of code! |
64 | /// usual I/O functionality, all without changing a single line of code! |
Line 217... | Line 222... | ||
217 | 222 | ||
218 | void bindThisThread(size_t) {} |
223 | void bindThisThread(size_t) {} |
219 | 224 | ||
220 | #else |
225 | #else |
221 | 226 | ||
222 | /// |
227 | /// best_group() retrieves logical processor information using Windows specific |
223 | /// API and returns the best group id for the thread with index idx. Original |
228 | /// API and returns the best group id for the thread with index idx. Original |
224 | /// code from Texel by Peter Ă–sterlund. |
229 | /// code from Texel by Peter Ă–sterlund. |
225 | 230 | ||
226 | int |
231 | int best_group(size_t idx) { |
227 | 232 | ||
228 | int threads = 0; |
233 | int threads = 0; |
229 | int nodes = 0; |
234 | int nodes = 0; |
230 | int cores = 0; |
235 | int cores = 0; |
231 | DWORD returnLength = 0; |
236 | DWORD returnLength = 0; |
232 | DWORD byteOffset = 0; |
237 | DWORD byteOffset = 0; |
233 | 238 | ||
234 | // Early exit if the needed API is not available at runtime |
239 | // Early exit if the needed API is not available at runtime |
235 | HMODULE k32 = GetModuleHandle("Kernel32.dll"); |
240 | HMODULE k32 = GetModuleHandle("Kernel32.dll"); |
236 | auto fun1 = (fun1_t)GetProcAddress(k32, "GetLogicalProcessorInformationEx"); |
241 | auto fun1 = (fun1_t)(void(*)())GetProcAddress(k32, "GetLogicalProcessorInformationEx"); |
237 | if (!fun1) |
242 | if (!fun1) |
238 | return -1; |
243 | return -1; |
239 | 244 | ||
240 | // First call to get returnLength. We expect it to fail due to null buffer |
245 | // First call to get returnLength. We expect it to fail due to null buffer |
241 | if (fun1(RelationAll, nullptr, &returnLength)) |
246 | if (fun1(RelationAll, nullptr, &returnLength)) |
Line 292... | Line 297... | ||
292 | /// bindThisThread() set the group affinity of the current thread |
297 | /// bindThisThread() set the group affinity of the current thread |
293 | 298 | ||
294 | void bindThisThread(size_t idx) { |
299 | void bindThisThread(size_t idx) { |
295 | 300 | ||
296 | // Use only local variables to be thread-safe |
301 | // Use only local variables to be thread-safe |
297 | int group = |
302 | int group = best_group(idx); |
298 | 303 | ||
299 | if (group == -1) |
304 | if (group == -1) |
300 | return; |
305 | return; |
301 | 306 | ||
302 | // Early exit if the needed API are not available at runtime |
307 | // Early exit if the needed API are not available at runtime |
303 | HMODULE k32 = GetModuleHandle("Kernel32.dll"); |
308 | HMODULE k32 = GetModuleHandle("Kernel32.dll"); |
304 | auto fun2 = (fun2_t)GetProcAddress(k32, "GetNumaNodeProcessorMaskEx"); |
309 | auto fun2 = (fun2_t)(void(*)())GetProcAddress(k32, "GetNumaNodeProcessorMaskEx"); |
305 | auto fun3 = (fun3_t)GetProcAddress(k32, "SetThreadGroupAffinity"); |
310 | auto fun3 = (fun3_t)(void(*)())GetProcAddress(k32, "SetThreadGroupAffinity"); |
306 | 311 | ||
307 | if (!fun2 || !fun3) |
312 | if (!fun2 || !fun3) |
308 | return; |
313 | return; |
309 | 314 | ||
310 | GROUP_AFFINITY affinity; |
315 | GROUP_AFFINITY affinity; |