在Win32上如何将线程移动到另一个CPU核心?

时间:2008-10-02 19:07:51

标签: c++ c multithreading winapi multicore

我想确保一个线程被移动到一个特定的CPU核心,并且永远不会被调度程序从它移动。

有一个SetThreadAffinityMask()来电,但没有GetThreadAffinityMask()

我需要这个的原因是因为如果调度程序将该线程移动到另一个CPU,高分辨率计时器将会搞乱。

4 个答案:

答案 0 :(得分:10)

您应该只使用SetThreadAffinityMask并相信它正在运行。

MSDN

答案 1 :(得分:4)

如果你可以调用一个函数来返回一个数字,该函数指示线程正在运行的CPU,而不使用亲和性,那么一旦函数返回,答案通常就会出错。因此,检查SetThreadAffinityMask()返回的掩码与在高级IRQL上运行的内核代码之外的even that's changing一样接近。

听起来你正试图解决RDTSC时钟偏差问题。如果您直接使用RDTSC指令,请考虑改为调用QueryPerformanceCounter()

    如果芯片组支持,则Windows Vista上的
  • QueryPerformanceCounter()使用HPET,并且位于系统的ACPI表中。
  • 如果您调用QueryPerformanceCounter(),使用AMD Processor Driver的基于AMD的系统将主要补偿多核时钟偏差,但这对直接使用RDTSC的应用程序没有任何作用。对于直接使用RDTSC的应用程序,AMD Dual-Core Optimizer是一个hack,但如果由于C1时钟斜坡(C1电源状态下时钟速度降低)导致时钟偏差量发生变化,那么还有时钟歪斜。这些实用程序可能不是很普遍,因此使用与QueryPerformanceCounter()的亲和力仍然是一个好主意。

答案 2 :(得分:3)

肯说。但是如果你不相信它正在工作,你可以再次调用SetThreadAffinityMask,并确认返回值与你期望的掩码相匹配。 (但当然,如果你不相信这个功能那么你就不能相信第二次通话......)

不要因为GetProcessAffinityMask的存在而感到困惑。该函数不用于验证SetProcessAffinityMask是否有效,但是例如所以你可以构造一个线程亲和力,它是进程亲和力的一个子集。

只要查看返回值并验证它不是0就可以了。

答案 3 :(得分:1)

不需要Get Thread AffinityMask。只需获取Get Process AffinityMask的值,关闭一些位,然后调用SetThreadAffinityMask。线程继承进程的亲和性掩码,由于它们的亲和力在你的控制之下,你已经知道线程的亲和性掩码(它是你设置它的那个)。