我的笔记本电脑有4个逻辑处理器(两个物理处理器);逻辑CPU 1和2映射到核1,逻辑CPU 3和4映射到核2(使用GetLogicalProcessorInformation()
验证)。
我在计算机上运行了一个带有两个线程的多线程矩阵乘法程序。我第一次使用SetProcessAffinityMask(hProcess, 0x5)
(这意味着逻辑处理器1和3),而第二次使用SetProcessAffinityMask(hProcess, 0xA)
(逻辑处理器2和4)。
事实证明,第一个版本的速度大约是第二个版本的两倍,就好像我从来没有多线程化过第二个版本。
有没有人猜测为什么会发生这种情况?
测量
已插入(完整CPU):
电池供电(时钟下降):
这是否意味着第四个逻辑CPU没有做任何事情(!)?(第四个CPU设置掩码的所有东西都很慢。)
更新
我刚刚在电池上的高性能配置文件上运行。结果是不一致的:这次,我为掩模5,6和10加速了2倍,但掩模12没有加速。我会尝试在交流电源上再次运行测试,但最终看起来像这样结果是电源管理,Turbo Boost,调度不一致等的组合,并且它比我之前想象的更难测量。 :(
答案 0 :(得分:1)
SetProcessAffinityMask()不保证每个核心都有一个线程;只有您拥有的线程才会在您允许的核心上运行。
也许操作系统的安排方式不同。
另外,我很惊讶1和2是核心1.通常,逻辑处理器号在物理核心上交错,以提供固有的负载平衡。我希望1和3在核心1,2和4上位于核心2上。
答案 1 :(得分:1)
不,并非所有核心都是平等的。只有一个是启动核心。此外,在许多情况下,所有IRQ(或至少来自大多数设备的IRQ)都指向单个核心。
对于您观察到的行为更重要,并非所有集核心都相同。在NUMA内存架构(自Intel超线程和AMD Opteron以来在x86中相对主流)中,有一个理想的处理器组可以有效地访问特定的内存区域,而所有其他处理器将会付出巨大的代价访问该范围。
对于超线程,它不是非均匀连接的主系统内存,而是L1和L2缓存。如果您的进程在与同一物理核心关联的两个虚拟处理器之间迁移,则缓存仍然有效。但是,如果它迁移到另一个物理核心,则必须复制缓存数据并将所有权转移到另一个缓存。对于某些工作负载,这可能会产生很大的不同。
答案 2 :(得分:0)
知道这是什么物理CPU会很好,但是我从你对逻辑处理器的措辞中假设有1个物理插槽,2个CPU内核和超线程启用,为你提供4个逻辑处理器。 / p>
简而言之,对于"处理器"的复杂定义,不,并非所有处理器都是相同的。超线程逻辑核心共享执行资源,如果存在对这些资源的争用,则它们不会像单独的物理核心一样快速。对于超线程和多核处理器(ALU,执行资源,不同级别的缓存等),这种共享可以在不同级别进行,但从广义上讲,同一插槽中的物理内核不会受到其他内容的影响。核心正在进行,超线程实现的逻辑核心将受到他们的高压正在做的巨大影响。
不同CPU之间的另一个区别:正如Ben所说,您的操作系统可能会处理单个CPU上的大多数硬件中断,这意味着CPU看起来会因其他目的而变慢,但如果中断负载足够,我会感到惊讶在这么近的地方影响性能。
你得到的结果 - 在处理器A和B上(故意模糊了哪两个处理器)你的性能是A的两倍,但在处理器A和C上,你获得的性能与A单独相同 - - 确保声音像超线程是不同的,其中A和C是同一物理核心中的高压,而B是另一个物理核心。你说GetLogicalProcessorInformation()声称不是这样,但对于那些依赖于错误的BIOS表来说并不是闻所未闻。
我会运行任务管理器,在运行测试之前密切关注每个CPU上的负载,以了解正在进行的其他操作以及Windows安排它的位置,然后再次运行测试几次,针对不同的CPU亲和力的组合,看看你是否可以证实或否认这一理论。
答案 3 :(得分:0)
您是否检查了SetProcessAffinityMask
的返回代码,看是否有错误?如果调用失败,您可能会卡在一个逻辑处理器上。根据{{3}},您只能使用GetProcessAffinityMask
结果中设置的位。
你说你曾尝试过0x5
,0xA
和0x9
的面具。我很想看到0x3
的结果。