我想让我的程序读取它在C++中运行的CPU该高速缓存线大小。我知道这不可能做到便携,所以我需要一个Linux和另一个Windows的解决方案(其他系统的解决方案可能对其他人有用,所以如果你知道的话,请发布它们)。对于Linux,我可以读取/proc/cpuinfo的内容并解析以cache_alignment开头的行,也许有一个更好的方法涉及到调用API。对于Windows,我根本不知道。
yi0zb3m41#
在Win32上,GetLogicalProcessorInformation将给予一个包含CACHE_DESCRIPTOR的SYSTEM_LOGICAL_PROCESSOR_INFORMATION,其中包含您需要的信息。
GetLogicalProcessorInformation
CACHE_DESCRIPTOR
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
cl25kdpy2#
在Linux上尝试proccpuinfo library,这是一个独立于体系结构的C API,用于阅读/proc/cpuinfo
vdgimpew3#
对于x86,CPUID指令。快速的谷歌搜索会发现一些用于win32和c++的libraries。我也通过内联汇编程序使用过CPUID。更多信息:
oyxsuwqo4#
看起来至少SCO unix(http://uw714doc.sco.com/en/man/html.3C/sysconf.3C.html)有_SC_CACHE_LINE用于sysconf。也许其他平台也有类似的东西?
_SC_CACHE_LINE
brqmpdu15#
在Windows上
#include <Windows.h> #include <iostream> using std::cout; using std::endl; int main() { SYSTEM_INFO systemInfo; GetSystemInfo(&systemInfo); cout << "Page Size Is: " << systemInfo.dwPageSize; getchar(); }
在Linux上
http://linux.die.net/man/2/getpagesize
9rbhqvlz6#
下面是一些示例代码,供那些想知道如何在接受答案中使用该函数的人参考:
#include <new> #include <iostream> #include <Windows.h> void ShowCacheSize() { using CPUInfo = SYSTEM_LOGICAL_PROCESSOR_INFORMATION; DWORD len = 0; CPUInfo* buffer = nullptr; // Determine required length of a buffer if ((GetLogicalProcessorInformation(buffer, &len) == FALSE) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { // Allocate buffer of required size buffer = new (std::nothrow) CPUInfo[len]{ }; if (buffer == nullptr) { std::cout << "Buffer allocation of " << len << " bytes failed" << std::endl; } else if (GetLogicalProcessorInformation(buffer, &len) != FALSE) { for (DWORD i = 0; i < len; ++i) { // This will be true for multiple returned caches, we need just one if (buffer[i].Relationship == RelationCache) { std::cout << "Cache line size is: " << buffer[i].Cache.LineSize << " bytes" << std::endl; break; } } } else { std::cout << "ERROR: " << GetLastError() << std::endl; } delete[] buffer; } }
llew8vvj7#
我认为您需要ntdll.dll中的NtQuerySystemInformation。
ntdll.dll
NtQuerySystemInformation
nbewdwxp8#
如果您的实现支持,C17 std::hardware_destructive_interference_size会给予您一个上限(..._constructive_...是一个下限),考虑到像行对的硬件预取这样的东西。但这些都是编译时常量,因此对于允许不同行大小的ISA,不可能在所有微体系结构上都是正确的。(例如,早期的x86 CPU(如Pentium III)有32字节的行,但所有后来的x86 CPU(包括所有x86-64)都使用64字节的行。理论上,未来的某些微体系结构可能会使用128字节的行,但是针对64字节行进行调优的多线程二进制代码非常普遍,因此这对于x86来说可能不太可能。)由于这个原因,一些当前的实现选择根本不实现C的特性。GCC实现了它,而clang没有(Godbolt)。当代码在结构体布局中使用它时,它就成为ABI的一部分,所以编译器在未来无法更改它以匹配未来CPU的相同目标。GCC将建设性和破坏性都定义为64 x86-64,忽略了相邻行预取可能导致的破坏性干扰,例如在英特尔Sandybridge系列上。在高争用情况下,它不像高速缓存行内的错误共享那样灾难性,因此您可以选择只使用64字节对齐来分隔不同线程将独立访问的对象。
std::hardware_destructive_interference_size
..._constructive_...
64
8条答案
按热度按时间yi0zb3m41#
在Win32上,
GetLogicalProcessorInformation
将给予一个包含CACHE_DESCRIPTOR
的SYSTEM_LOGICAL_PROCESSOR_INFORMATION
,其中包含您需要的信息。cl25kdpy2#
在Linux上尝试proccpuinfo library,这是一个独立于体系结构的C API,用于阅读/proc/cpuinfo
vdgimpew3#
对于x86,CPUID指令。快速的谷歌搜索会发现一些用于win32和c++的libraries。我也通过内联汇编程序使用过CPUID。
更多信息:
oyxsuwqo4#
看起来至少SCO unix(http://uw714doc.sco.com/en/man/html.3C/sysconf.3C.html)有
_SC_CACHE_LINE
用于sysconf。也许其他平台也有类似的东西?brqmpdu15#
在Windows上
在Linux上
http://linux.die.net/man/2/getpagesize
9rbhqvlz6#
下面是一些示例代码,供那些想知道如何在接受答案中使用该函数的人参考:
llew8vvj7#
我认为您需要
ntdll.dll
中的NtQuerySystemInformation
。nbewdwxp8#
如果您的实现支持,C17
std::hardware_destructive_interference_size
会给予您一个上限(..._constructive_...
是一个下限),考虑到像行对的硬件预取这样的东西。但这些都是编译时常量,因此对于允许不同行大小的ISA,不可能在所有微体系结构上都是正确的。(例如,早期的x86 CPU(如Pentium III)有32字节的行,但所有后来的x86 CPU(包括所有x86-64)都使用64字节的行。理论上,未来的某些微体系结构可能会使用128字节的行,但是针对64字节行进行调优的多线程二进制代码非常普遍,因此这对于x86来说可能不太可能。)
由于这个原因,一些当前的实现选择根本不实现C的特性。GCC实现了它,而clang没有(Godbolt)。当代码在结构体布局中使用它时,它就成为ABI的一部分,所以编译器在未来无法更改它以匹配未来CPU的相同目标。
GCC将建设性和破坏性都定义为
64
x86-64,忽略了相邻行预取可能导致的破坏性干扰,例如在英特尔Sandybridge系列上。在高争用情况下,它不像高速缓存行内的错误共享那样灾难性,因此您可以选择只使用64字节对齐来分隔不同线程将独立访问的对象。