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

发布于 2024-07-05 21:13:39 字数 194 浏览 8 评论 0原文

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

SetThreadAffinityMask() 调用,但没有 GetThreadAffinityMask()

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

I'd like to make sure that a thread is moved to a specific CPU core and can never be moved from it by the scheduler.

There's a SetThreadAffinityMask() call but there's no GetThreadAffinityMask().

The reason I need this is because high resolution timers will get messed up if the scheduler moves that thread to another CPU.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

依 靠 2024-07-12 21:13:40

如果您可以调用一个函数,该函数返回一个数字,指示线程正在哪个 CPU 上运行,而不使用关联性,那么一旦函数返回,答案通常会是错误的。 因此,在以提升的 IRQL 运行的内核代码之外,检查 SetThreadAffinityMask() 返回的掩码是尽可能接近的,并且 即使这样也在改变

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

If you could call a function that returns a number indicating what CPU the thread is running on, without using affinity, the answer would often be wrong as soon as the function returned. So checking the mask returned by SetThreadAffinityMask() is as close as you're going to get, outside of kernel code running at elevated IRQL, and even that's changing.

It sounds like you're trying to work around RDTSC clock skew issues. If you are using the RDTSC instruction directly, consider calling QueryPerformanceCounter() instead:

  • QueryPerformanceCounter() on Windows Vista uses the HPET if it is supported by the chipset and is in the system's ACPI tables.
  • AMD-based systems using the AMD Processor Driver will mostly compensate for multi-core clock skew if you call QueryPerformanceCounter(), but this does nothing for applications that use RDTSC directly. The AMD Dual-Core Optimizer is a hack for applications that use RDTSC directly, but if the amount of clock skew is changing due to C1 clock ramping (where the clock speed is reduced in the C1 power state), you will still have clock skew. And these utilities probably aren't very widespread, so using affinity with QueryPerformanceCounter() is still a good idea.
梦里兽 2024-07-12 21:13:40

您可能应该只使用 SetThreadAffinityMask 并相信它正在工作。

MSDN

You should probably just use SetThreadAffinityMask and trust that it is working.

MSDN

我要还你自由 2024-07-12 21:13:40

不需要 GetThreadAffinityMask。 只需获取 GetProcessAffinityMask 的值,关闭一些位,然后调用 SetThreadAffinityMask。 线程继承进程的亲和性掩码,并且由于它们的亲和性在您的控制之下,因此您已经知道线程的亲和性掩码(这是您设置的亲和性掩码)。

There is no need for GetThreadAffinityMask. Just get the value of GetProcessAffinityMask, turn some bits off, then call SetThreadAffinityMask. The threads inherit the process' affinity mask, and since their affinity is under your control, you already know a thread's affinity mask (it's the one you set it to).

温暖的光 2024-07-12 21:13:40

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

不要对 GetProcessAffinityMask 的存在感到困惑。 该函数不是用来验证 SetProcessAffinityMask 是否有效,而是用于构造一个线程亲和性,它是进程亲和性的子集。

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

What Ken said. But if you don't trust it's working, you can call SetThreadAffinityMask again, and confirm that the return value matches what you expect the mask to be. (But then of course, if you don't trust the function then you can't trust the second call...)

Don't be confused by the existence of GetProcessAffinityMask. That function is not there to verify that SetProcessAffinityMask worked, but e.g. so you can construct a thread affinity that is a subset of process affinity.

Just look that the return value and verify that it isn't 0 and you should be fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文