正如我在Ira Baxter的回答中暗示的那样,CPU 缓存也在多核系统中发挥作用。考虑以下测试代码:
危险将罗宾逊!
以下代码将优先级提高到实时以实现更一致的结果 - 虽然这样做需要管理员权限,但在双核或单核系统上运行代码时要小心,因为您的机器将在测试运行期间锁定。
#include <windows.h>
#include <stdio.h>
const int RUNFOR = 5000;
volatile bool terminating = false;
volatile int value;
static DWORD WINAPI CountErrors(LPVOID parm)
{
int errors = 0;
while(!terminating)
{
value = (int) parm;
if(value != (int) parm)
errors++;
}
printf("\tThread %08X: %d errors\n", parm, errors);
return 0;
}
static void RunTest(int affinity1, int affinity2)
{
terminating = false;
DWORD dummy;
HANDLE t1 = CreateThread(0, 0, CountErrors, (void*)0x1000, CREATE_SUSPENDED, &dummy);
HANDLE t2 = CreateThread(0, 0, CountErrors, (void*)0x2000, CREATE_SUSPENDED, &dummy);
SetThreadAffinityMask(t1, affinity1);
SetThreadAffinityMask(t2, affinity2);
ResumeThread(t1);
ResumeThread(t2);
printf("Running test for %d milliseconds with affinity %d and %d\n", RUNFOR, affinity1, affinity2);
Sleep(RUNFOR);
terminating = true;
Sleep(100); // let threads have a chance of picking up the "terminating" flag.
}
int main()
{
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
RunTest(1, 2); // core 1 & 2
RunTest(1, 4); // core 1 & 3
RunTest(4, 8); // core 3 & 4
RunTest(1, 8); // core 1 & 4
}
在我的四核英特尔 Q6600 系统上(iirc 有两组内核,每组共享 L2 缓存 - 无论如何都会解释结果;)),我得到以下结果:
使用亲和力 1 和 2 运行 5000 毫秒的测试
线程 00002000:351883 错误
线程 00001000:343523 错误
以亲和力 1 和 4 运行 5000 毫秒的测试
线程 00001000:48073 错误
线程 00002000:59813 错误
以亲和力 4 和 8 运行 5000 毫秒的测试
线程 00002000:337199 错误
线程 00001000:335467 错误
以亲和力 1 和 8 运行 5000 毫秒的测试
线程 00001000:55736 错误
线程 00002000:72441 错误