C# 如何确定线程在哪个CPU上运行?

C# 如何确定线程在哪个CPU上运行?,c#,c++,multithreading,C#,C++,Multithreading,有没有办法确定给定线程在哪个CPU上运行? 最好是C,但是C++可以。 .NET进程和ProcessThread类似乎没有提供这些信息 ETA澄清: 我们正在开发一个服务器应用程序,它可以处理http多播流并生成多个视频编码器。它在具有12个物理内核的系统上运行,从而产生24个逻辑CPU(超线程)。通过TaskManager和ProcessExplorer,我们已验证生成的进程是否均匀分布在逻辑CPU上。然而,我们在一个CPU上看到了大量(内核?)活动,这些活动会消耗大量的CPU时间,从而产生干

有没有办法确定给定线程在哪个CPU上运行? 最好是C,但是C++可以。

.NET进程和ProcessThread类似乎没有提供这些信息

ETA澄清:

我们正在开发一个服务器应用程序,它可以处理http多播流并生成多个视频编码器。它在具有12个物理内核的系统上运行,从而产生24个逻辑CPU(超线程)。通过TaskManager和ProcessExplorer,我们已验证生成的进程是否均匀分布在逻辑CPU上。然而,我们在一个CPU上看到了大量(内核?)活动,这些活动会消耗大量的CPU时间,从而产生干扰。我们正试图确定哪个进程/线程正在这个特定的CPU上运行。TaskManager和ProcessExplorer似乎都没有提供这些信息。如果有,请解释如何获得此类信息

否则,我们正在考虑编写自己的工具来获取这些信息。这就是我们需要帮助的地方

我们知道如何更改线程关联性(并且我们知道不能保证线程将与任何CPU保持关联,尽管在这种特殊情况下,消耗CPU的线程只与一个CPU保持关联),但是为了这样做,我们需要首先确定需要重新定位哪个进程/线程。这是这个问题的唯一目的

我希望这有助于澄清问题。

从中,使用ProcessThread.ProcessorAffinity属性可以设置线程关联,但无法获得它。默认情况下,线程没有关联(可以在任何处理器上操作)


类似地,
Thread.SetProcessorAffinity
也做同样的事情

这不可能以持续可靠的方式进行。OS任务调度器优化线程并在可用CPU内核之间分配负载。一般情况下,线程可以在任何CPU上执行。此外,通过上下文切换,它还可以改变它的CPU


如果您需要固定特定于点的线程或进程,则只能分配其关联性,这样您就有理由希望该进程/线程将在特定的逻辑CPU上执行。

自Vista/Server2003以来,您可以PInvoke
GetCurrentProcessorNumber()
Windows API方法()

很明显,Windows仅适用于其他平台,因此如果您计划支持其他平台,这并不理想


我不确定OP的用例是否理想,但当试图创建一个保证在系统中唯一的时间戳时,它可能是明智的/有用的,即使所有处理器都在同一时间计算一个时间戳。

您试图用这些信息解决什么问题?这只为内核所知。所以你需要在内核模式下编程。在MSDN上查找内核API。如果一个线程在不同的时间在多个不同的CPU上运行,您希望它做什么?我们在一个有12个内核的系统上运行一个复杂的应用程序。出于我们需要了解的原因,我们只在一个内核上看到了CPU使用率的峰值。我们想知道哪些线程(以及哪些进程或服务)正在这个特定的核心上运行。我们不知道有哪种工具能提供这些信息,并考虑自己写一篇文章。这不是一个有效的问题。这不是关于哪个CPU,而是关于为什么这个所谓的多线程程序不使用多个CPU。在适当的探查器中检查线程负载,您可能会发现存在处理瓶颈。Visual Studio有ap profiler用于这种类型的分析。此外,线程会四处移动,因此即使您能得到答案,在您尝试检查某些内容时也不一定有效。是的,Process和ProcessThread上的ProcessorAffinity属性是我的第一个希望,但正如您指出的,我无法得到它…@TomTom:是的,它们可以被移动,但在我们的例子中,快照已经提供了有价值的信息。@Harald隐式地说,如果您设置了处理器亲缘关系,您就知道它是什么。您使用的是第三方组件吗?您需要了解其亲和力吗?@Harald您是否尝试过使用第三方分析应用程序,如JetBrains dotTrace(强烈推荐)或ANTS Profiler?虽然从技术上讲是正确的,但您的答案缺少非常重要的一点。了解您当前的CPU可以通过占用共享资源显著减少争用。是的,在极少数情况下,您将被中断并移动到其他核心。这意味着仍然需要同步。但是性能结果是无与伦比的。@KirillKobelev你能给我一些参考吗。我可以看到它在低级别上工作,但不确定如何从应用程序管理它。你在谈论NUMA吗?想想
intcnt[num_cores]的性能;联锁增量(cnt[GetCurrCore())vs只有一个计数器的简单版本。类似的切分(如上所述)可以在托管线程ID上完成。无论如何,我想知道这样的问题是否也可以在(初始化)CPU内核上完成。我猜不那么容易。。在某些情况下,通过托管ID进行分片仍然非常有用,可以显著减少锁争用。
using System;
using System.Diagnostics;

namespace ProcessThreadIdealProcessor
{
    class Program
    {
        static void Main(string[] args)
        {
            // Make sure there is an instance of notepad running.
            Process[] notepads = Process.GetProcessesByName("notepad");
            if (notepads.Length == 0)
                Process.Start("notepad");
            ProcessThreadCollection threads;
            //Process[] notepads;
            // Retrieve the Notepad processes.
            notepads = Process.GetProcessesByName("Notepad");
            // Get the ProcessThread collection for the first instance
            threads = notepads[0].Threads;
            // Set the properties on the first ProcessThread in the collection
            threads[0].IdealProcessor = 0;
            threads[0].ProcessorAffinity = (IntPtr)1;
        }
    }
}