14

我正在对软件进行基准测试,该软件在 Intel 2670QM 上的执行速度比我使用所有 8 个“逻辑”线程的串行版本快 4 倍。我想要一些关于我对基准测试结果的看法的社区反馈。

当我在 4 个内核上使用 4 个线程时,我的速度提高了 4 倍,整个算法是并行执行的。这对我来说似乎是合乎逻辑的,因为“阿姆达尔定律”预测了这一点。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。

4

5 回答 5

14

i7-2670QM处理器有 4 个内核。但它可以并行运行 8 个线程。这意味着它只有 4 个处理单元(核心),但硬件支持并行运行 8 个线程。这意味着在核心上最多运行四个作业,如果其中一个作业由于例如内存访问而停止,另一个线程可以非常快速地开始在空闲核心上执行而几乎没有损失。阅读有关超线程的更多信息。在现实中,很少有超线程能够大幅提升性能的场景。更现代的处理器比旧处理器更好地处理超线程。

您的基准测试表明它受 CPU 限制,即管道中几乎没有停滞,这会给超线程带来优势。50% CPU 是正确的,其中 4 个内核正在工作,而额外的 4 个内核没有做任何事情。在 BIOS 中打开超线程,您将看到 100% CPU。

于 2012-05-01T20:00:20.693 回答
12

这是超线程的快速总结

线程切换很慢,必须停止执行,将一堆值复制到内存中,将一堆值从内存中复制到 CPU 中,然后用新线程重新开始。

这就是你的 4 个虚拟内核的用武之地。你有 4 个内核,就是这样,但超线程允许 CPU 做的是在一个内核上有 2 个线程。

一次只能执行 1 个线程,但是当 1 个线程需要停止执行内存访问、磁盘访问或其他需要一些时间的操作时,它可以切换到另一个线程并运行一段时间。在旧处理器上,这段时间他们基本上睡了一会儿。

因此,您的四核有 4 个内核,每个内核一次可以做一件事,但是当他们需要在计算机的另一部分等待时,可以有第二个工作处于待机状态。

如果您的任务有大量内存使用和大量 CPU 使用,您应该会看到总执行时间略有减少,但如果您几乎完全受 CPU 限制,您最好坚持使用 4 个线程

于 2012-05-01T19:45:08.923 回答
10

这里要理解的重要信息是物理线程和逻辑线程之间的区别。
如果您的 CPU 上有 4 个物理内核,这意味着您有物理资源可以并行执行 4 个不同的执行线程。因此,如果您的线程没有数据争用,与单线程的速度相比,您通常可以测量出 x4 的性能提升。
我还假设操作系统(或您:))正确设置了线程关联,因此每个线程都在每个物理核心上运行。
当您在 CPU 上启用 HT(超线程)时,核心频率不会被修改。:)那部分
会发生什么硬件管道的一部分(在核心内部和周围(非核心、缓存等))是重复的,但它的一部分仍然在逻辑线程之间共享。这就是您不测量 x8 性能提升的原因。根据我启用所有逻辑核心的经验,您可以获得每个物理核心 x1.5 - x1.7 的性能提升,具体取决于您正在执行的代码、缓存使用情况(请记住,L1 缓存在两个逻辑核心/1 个物理核心之间共享,例如)、线程亲和性等等。希望这可以帮助。

于 2012-05-01T20:00:08.340 回答
1

HT 在大多数 BIOS 中称为 SMT(同时多线程)或 HTT(超线程技术)。HT 的效率取决于所谓的计算与获取比率,即您的代码在从慢速主内存或 I/O 内存中获取或存储之前执行了多少内核(或寄存器/缓存)操作。对于高速缓存效率和 CPU 密集型代码,HT 几乎没有提供明显的性能提升。对于更多的内存绑定代码,由于所谓的“延迟隐藏”,HT 可以真正使执行受益。这就是为什么大多数非 x86 服务器 CPU 为每个内核提供 4(例如 IBM POWER7)到 8(例如 UltraSPARC T4)硬件线程。这些 CPU 通常用于数据库和事务处理系统,在这些系统中一次处理许多并发的内存绑定请求。

顺便说一句,Amdhal 定律指出,并行加速的上限是代码串行分数的 1 倍。通常,如果线程之间存在(可能隐藏在运行时中)通信或其他同步,则串行部分会随着处理元素的数量而增加,尽管有时缓存效果会导致超线性加速,有时缓存垃圾会大大降低性能。

于 2012-05-04T11:41:59.923 回答
0

一些实际数字:

我的 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
于 2012-05-01T21:40:55.403 回答