我是基准测试软件,它在Intel 2670QM上运行速度提高4倍,然后使用我所有8个“逻辑”线程执行我的串行版本。我希望社群对我对基准测试结果的看法提供反馈。
当我在4个核心上使用4个线程时,我的速度提高了4倍,整个算法都是并行执行的。这对我来说似乎合乎逻辑,因为'Amdhals law'预测它。 Windows任务管理器告诉我,我正在使用50%的CPU。
但是,如果我在所有8个线程上执行相同的软件,我再次加速4倍,不加速8倍。
如果我已正确理解这一点:我的CPU有4个内核,频率为2.2GHZ,但当应用于8'逻辑'线程时,频率被分为1.1GHZ,其余部分如下所示缓存?如果这是真的那么为什么任务管理器只声称我的CPU有50%被使用?
#define NumberOfFiles 8
...
char startLetter ='a';
#pragma omp parallel for shared(startLetter)
for(int f=0; f<NumberOfFiles; f++){
...
}
我不包括使用磁盘I / O的时间。我只对STL调用(STL排序)而不是磁盘I / O的时间感兴趣。
答案 0 :(得分:12)
i7-2670QM处理器有4个核心。但它可以并行运行8个线程。 这意味着它只有4个处理单元(Cores),但在硬件上支持并行运行8个线程。这意味着在Cores上最多运行四个作业,如果其中一个作业由于例如内存访问而停止,则另一个线程可以非常快速地开始在免费Core上执行,而且损失很小。 Read more on Hyper threading。在Reality中,极少数情况下超线程可以带来很大的性能提升。更现代的处理器比旧处理器更好地处理超线程。
你的基准测试显示它受CPU限制,即管道中的小停顿会给超线程带来优势。 50%的CPU是正确的,4核正在工作,4额外没有做任何事情。在BIOS中关闭超线程,您将看到100%的CPU。
答案 1 :(得分:8)
这是Hyperthreading / HyperTransport的快速摘要
线程切换很慢,不得不停止执行,将一堆值复制到内存中,将一堆值从内存中复制到CPU中,然后用新线程重新开始。
这就是你的4个虚拟内核的用武之地。你有4个内核,就是它,但是超线程允许CPU做的是在一个内核上有2个线程。
一次只能执行一个线程,但是当1个线程需要停止进行内存访问,磁盘访问或其他任何需要一些时间的线程时,它可以切换到另一个线程并运行它位。在旧的处理器上,他们在这个时候基本上都有一点睡眠。
所以你的四核有4个内核,每个内核可以做一件事,但是只要他们需要在计算机的另一部分等待就可以让第二个作业处于待机状态。
如果你的任务有大量的内存使用量和大量的CPU使用率,你应该看到总执行时间略有减少,但是如果你几乎完全受CPU限制,你最好只坚持4个线程
答案 2 :(得分:8)
这里要理解的重要信息是物理和逻辑线程之间的区别。
如果CPU上有4个物理内核,则意味着您拥有物理资源来并行执行4个不同的执行线程。因此,如果您的线程没有数据争用,那么与单线程的速度相比,通常可以测量x4性能提升。
我还假设OS(或你:))正确设置线程关联,因此每个线程都在每个物理核心上运行。
在CPU上启用HT(超线程)时,核心频率不会被修改。 :)
发生的事情是hw管道的部分(在核心内部和周围(uncore,缓存等))是重复的,但它的一部分仍然在逻辑线程之间共享。
这就是为什么你不测量x8性能提升的原因。根据我使用所有逻辑核心的经验,每个物理核心可以获得x1.5 - x1.7的性能提升,具体取决于您执行的代码,缓存使用情况(请记住,L1缓存在两个逻辑核心/ 1个物理核心之间共享) ,例如),线程关联,等等。
希望这会有所帮助。
答案 3 :(得分:1)
一些实际数字:
我的i7上的CPU密集型任务(将数字从1-1000000000添加到int var中,16次),平均超过8次测试:
摘要,主题/标记:
1/26414
4/8923
8/6659
12/6592
16/6719
64/6811
128/6778
请注意,在下面的报告中的“使用X个线程”行中,X比可用于完成任务的线程数大一个 - 一个线程提交任务并等待倒计时锁定evnet完成 - 它不会处理任何CPU繁重的任务,也不会使用CPU。
8 tests,
16 tasks,
counting to 1000000000,
using 2 threads:
Ticks: 26286
Ticks: 26380
Ticks: 26317
Ticks: 26474
Ticks: 26442
Ticks: 26426
Ticks: 26474
Ticks: 26520
Average: 26414 ms
8 tests,
16 tasks,
counting to 1000000000,
using 5 threads:
Ticks: 8799
Ticks: 9157
Ticks: 8829
Ticks: 9002
Ticks: 9173
Ticks: 8720
Ticks: 8830
Ticks: 8876
Average: 8923 ms
8 tests,
16 tasks,
counting to 1000000000,
using 9 threads:
Ticks: 6615
Ticks: 6583
Ticks: 6630
Ticks: 6599
Ticks: 6521
Ticks: 6895
Ticks: 6848
Ticks: 6583
Average: 6659 ms
8 tests,
16 tasks,
counting to 1000000000,
using 13 threads:
Ticks: 6661
Ticks: 6599
Ticks: 6552
Ticks: 6630
Ticks: 6583
Ticks: 6583
Ticks: 6568
Ticks: 6567
Average: 6592 ms
8 tests,
16 tasks,
counting to 1000000000,
using 17 threads:
Ticks: 6739
Ticks: 6864
Ticks: 6599
Ticks: 6693
Ticks: 6676
Ticks: 6864
Ticks: 6646
Ticks: 6677
Average: 6719 ms
8 tests,
16 tasks,
counting to 1000000000,
using 65 threads:
Ticks: 7223
Ticks: 6552
Ticks: 6879
Ticks: 6677
Ticks: 6833
Ticks: 6786
Ticks: 6739
Ticks: 6802
Average: 6811 ms
8 tests,
16 tasks,
counting to 1000000000,
using 129 threads:
Ticks: 6771
Ticks: 6677
Ticks: 6755
Ticks: 6692
Ticks: 6864
Ticks: 6817
Ticks: 6849
Ticks: 6801
Average: 6778 ms
答案 4 :(得分:1)
顺便说一句,Amdhal定律指出并行加速的上限是代码的连续分数的一个上限。通常,如果存在(可能隐藏在运行时中)通信或线程之间的其他同步,则序列分数随着处理元素的数量而增加,尽管有时高速缓存效应可能导致超线性加速,有时高速缓存可能会大大降低性能。