Skip to content

Commit 9cdbbee

Browse files
committed
Implement get_num_physical_cores() for Windows
1 parent f4cef87 commit 9cdbbee

File tree

2 files changed

+75
-17
lines changed

2 files changed

+75
-17
lines changed

examples/common.cpp

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,11 @@
1515
#endif
1616

1717
#if defined (_WIN32)
18+
#define WIN32_LEAN_AND_MEAN
19+
#define NOMINMAX
20+
#include <windows.h>
1821
#include <fcntl.h>
1922
#include <io.h>
20-
#pragma comment(lib,"kernel32.lib")
21-
extern "C" __declspec(dllimport) void* __stdcall GetStdHandle(unsigned long nStdHandle);
22-
extern "C" __declspec(dllimport) int __stdcall GetConsoleMode(void* hConsoleHandle, unsigned long* lpMode);
23-
extern "C" __declspec(dllimport) int __stdcall SetConsoleMode(void* hConsoleHandle, unsigned long dwMode);
24-
extern "C" __declspec(dllimport) int __stdcall SetConsoleCP(unsigned int wCodePageID);
25-
extern "C" __declspec(dllimport) int __stdcall SetConsoleOutputCP(unsigned int wCodePageID);
26-
extern "C" __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int CodePage, unsigned long dwFlags,
27-
const wchar_t * lpWideCharStr, int cchWideChar,
28-
char * lpMultiByteStr, int cbMultiByte,
29-
const char * lpDefaultChar, bool * lpUsedDefaultChar);
3023
#define CP_UTF8 65001
3124
#endif
3225

@@ -60,7 +53,71 @@ int32_t get_num_physical_cores() {
6053
return num_physical_cores;
6154
}
6255
#elif defined(_WIN32)
63-
//TODO: Implement
56+
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buffer = nullptr;
57+
DWORD length = 0;
58+
59+
// Call GetLogicalProcessorInformationEx with a nullptr buffer to get the required buffer length
60+
GetLogicalProcessorInformationEx(RelationAll, nullptr, &length);
61+
62+
// Allocate memory for the buffer
63+
buffer = static_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *>(malloc(length));
64+
65+
// Things to count
66+
unsigned int physical_cores = 0;
67+
unsigned int physical_performance_cores = 0;
68+
unsigned int physical_efficiency_cores = 0;
69+
unsigned int logical_cores = 0;
70+
unsigned int logical_performance_cores = 0;
71+
unsigned int logical_efficiency_cores = 0;
72+
73+
// Call GetLogicalProcessorInformationEx again with the allocated buffer
74+
if (GetLogicalProcessorInformationEx(RelationAll, buffer, &length)) {
75+
DWORD offset = 0;
76+
77+
while (offset < length) {
78+
auto info = reinterpret_cast<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *>(reinterpret_cast<char *>(buffer) + offset);
79+
80+
if (info->Relationship == RelationProcessorCore) {
81+
physical_cores += info->Processor.GroupCount;
82+
83+
for (WORD i = 0; i < info->Processor.GroupCount; ++i) {
84+
int core_count = static_cast<int>(__popcnt64(info->Processor.GroupMask[i].Mask));
85+
logical_cores += core_count;
86+
87+
// Assuming EfficiencyClass 0 represents performance cores, and others represent efficiency cores
88+
if (info->Processor.EfficiencyClass == 0) {
89+
physical_performance_cores++;
90+
logical_performance_cores += core_count;
91+
} else {
92+
physical_efficiency_cores++;
93+
logical_efficiency_cores += core_count;
94+
}
95+
}
96+
}
97+
offset += info->Size;
98+
}
99+
100+
// TODO: Remove this once we've verified it's working
101+
fprintf(stderr,
102+
"Physical Cores: %u\n"
103+
" - Performance Cores: %u\n"
104+
" - Efficiency Cores: %u\n"
105+
"Logical Cores: %u\n"
106+
" - Performance Cores: %u\n"
107+
" - Efficiency Cores: %u\n",
108+
physical_cores, physical_performance_cores, physical_efficiency_cores,
109+
logical_cores, logical_performance_cores, logical_efficiency_cores);
110+
} else {
111+
printf("Failed to get processor information. Error: %u\n", GetLastError());
112+
}
113+
114+
free(buffer);
115+
116+
if (physical_performance_cores > 0) {
117+
return static_cast<int32_t>(physical_performance_cores);
118+
} else if (physical_cores > 0) {
119+
return static_cast<int32_t>(physical_cores);
120+
}
64121
#endif
65122
unsigned int n_threads = std::thread::hardware_concurrency();
66123
return n_threads > 0 ? (n_threads <= 4 ? n_threads : n_threads / 2) : 4;
@@ -69,7 +126,6 @@ int32_t get_num_physical_cores() {
69126
bool gpt_params_parse(int argc, char ** argv, gpt_params & params) {
70127
bool invalid_param = false;
71128
std::string arg;
72-
gpt_params default_params;
73129

74130
for (int i = 1; i < argc; i++) {
75131
arg = argv[i];
@@ -287,7 +343,7 @@ bool gpt_params_parse(int argc, char ** argv, gpt_params & params) {
287343
}
288344
params.n_parts = std::stoi(argv[i]);
289345
} else if (arg == "-h" || arg == "--help") {
290-
gpt_print_usage(argc, argv, default_params);
346+
gpt_print_usage(argc, argv);
291347
exit(0);
292348
} else if (arg == "--random-prompt") {
293349
params.random_prompt = true;
@@ -299,20 +355,22 @@ bool gpt_params_parse(int argc, char ** argv, gpt_params & params) {
299355
params.input_prefix = argv[i];
300356
} else {
301357
fprintf(stderr, "error: unknown argument: %s\n", arg.c_str());
302-
gpt_print_usage(argc, argv, default_params);
358+
gpt_print_usage(argc, argv);
303359
exit(1);
304360
}
305361
}
306362
if (invalid_param) {
307363
fprintf(stderr, "error: invalid parameter for argument: %s\n", arg.c_str());
308-
gpt_print_usage(argc, argv, default_params);
364+
gpt_print_usage(argc, argv);
309365
exit(1);
310366
}
311367

312368
return true;
313369
}
314370

315-
void gpt_print_usage(int /*argc*/, char ** argv, const gpt_params & params) {
371+
void gpt_print_usage(int /*argc*/, char ** argv) {
372+
gpt_params params;
373+
316374
fprintf(stderr, "usage: %s [options]\n", argv[0]);
317375
fprintf(stderr, "\n");
318376
fprintf(stderr, "options:\n");

examples/common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct gpt_params {
6767

6868
bool gpt_params_parse(int argc, char ** argv, gpt_params & params);
6969

70-
void gpt_print_usage(int argc, char ** argv, const gpt_params & params);
70+
void gpt_print_usage(int argc, char ** argv);
7171

7272
std::string gpt_random_prompt(std::mt19937 & rng);
7373

0 commit comments

Comments
 (0)