【问题标题】:Preventing Windows from changing process affinity防止 Windows 更改进程关联
【发布时间】:2014-04-30 09:57:59
【问题描述】:

我有一个多线程代码,我想在我的处理器拥有的所有 4 个内核上运行。 IE。我创建了四个线程,我希望它们中的每一个都在单独的核心上运行。

发生的情况是它开始在四个内核上运行,但偶尔会切换到仅三个内核。唯一运行的是操作系统和我的 exe。这有点令人失望,因为它将性能降低了四分之一,这对我来说已经足够重要了。

我在任务管理器中看到的进程关联性允许进程使用任何核心。我尝试限制线程关联,但没有帮助。我也尝试增加进程的优先级,但也无济于事。

所以问题是,有没有办法强制 Windows 让它在所有四个内核上运行?如果这是不可能的,我可以减少这些中断的频率吗?谢谢!

【问题讨论】:

    标签: windows multithreading scheduling affinity


    【解决方案1】:

    除非我大错特错,否则这不是亲和力问题。当然,系统不会将您的进程限制为与特定线程集的关联。如果确实发生了这种情况,系统中的其他一些程序将不得不这样做。

    但更可能的是,简单地说,系统正在以循环方式调度另一个准备运行的线程。您有四个随时准备运行的线程。如果有另一个线程准备运行,它将轮到它。现在有 5 个线程共享 4 个处理器。当另一个线程运行时,你的只有 3 个可以运行。

    如果您想确保此类其他线程不会运行,那么您需要执行以下操作之一:

    1. 停止运行其他想要使用 CPU 资源的程序。
    2. 设置相对线程优先级,以便您的线程始终优先于其他线程运行。

    现在,在这些选项中,第一个是首选。如果您将您的线程优先于其他线程,那么其他线程根本无法运行。这真的是你想要发生的事情吗?

    在您说没有其他进程在运行的问题中。如果是这种情况,并且没有人干预处理器亲和性,并且只有一部分线程正在执行,那么唯一的结论是并非所有线程都准备好运行并且有工作要做。例如,如果您在一个工作部分结束时加入线程,然后继续下一个工作,则可能会发生这种情况。

    也许下一步对您来说是缩小范围。使用 Process Explorer 之类的工具来诊断哪些线程正在实际运行。

    【讨论】:

    • 感谢您的回答。好吧,我可能应该清楚地说明我个人不太关心其他进程——只要我的进程运行需要,我就需要我的进程和一些系统东西。此外,我的线程很简单 for 循环,它们总是“准备好运行”。另一个问题是它们偶尔会完成并且我运行一个新批次,所以这可能是另一个过程发生的时候。
    • 如果它们始终准备好运行,那么调度程序将运行它们。您是否随时加入您的主题?
    • 好吧,我可以保证我的所有 4 个线程都被执行,但在 3 个内核上。是的,正如我所说,他们偶尔会完成他们的工作,我开始一组新的 4 个线程。这很可能是它被切换到 3 个核心的地方。我会再次尝试增加优先级,但到目前为止,这只会导致其他核心的优先级增加。
    • 我怀疑优先级会有所帮助。如果真的没有其他线程准备好运行,为什么系统不安排你准备运行的线程呢?唯一的结论是它还没有准备好运行。通常这意味着它正在阻塞。
    • 系统是否更愿意将一个核心上的处理器时间分配给某个后台系统进程?
    【解决方案2】:

    如果是windows,试试SetThreadAffinityMask():

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms686247(v=vs.85).aspx

    我假设如果您只设置一个位,那么这会强制线程仅在选定的处理器(内核)上运行。

    其他进程/线程函数:

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms684847(v=vs.85).aspx

    我使用了一个 windows 视频程序,它能够在渲染视频时让所有内核以接近最大的速度运行。

    【讨论】:

    • 感谢您的回答。但是,正如我所说,我尝试限制线程关联,但没有奏效。我认为改变的是进程亲和性,线程亲和性总是尊重进程亲和性。
    • 这是窗口吗?您是否使用了 SetThreadAffinityMask()(每个线程都需要调用一次),或者您是否尝试使用任务管理器执行此操作?那个windows视频程序我用过很多次了,从没见过渲染的时候不使用所有内核,所以可以防止线程切换内核。
    • 是的,它是 Windows,我使用了 SetThreadAffinityMask(),并为每个线程调用了一次。
    • 所以我假设对于每个线程的每次调用,您只设置了 1 位?如果是这样,那应该行得通。我不确定视频程序在渲染时如何避免这个问题。
    • @PeterKravchuk 在我看来,您在猜测亲和力是问题所在。验证这一点非常容易。不要猜测。检查你的亲和力。您可以从 Process Explorer 轻松阅读这些内容。或者你可以在你的程序中检查它们。绝对不要让你的线程只与一个处理器相关联。那会损害你的表现。不要在代码中设置任何关联。让系统调度你的线程。只有系统才能看到全貌。
    猜你喜欢
    • 2021-09-01
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 2011-01-22
    相关资源
    最近更新 更多