超线程在 AVX 上有问题吗?
Does Hyperthreading have trouble with AVX?
在进行超频和 运行 烧录测试时,我注意到 LINPACK 的 AVX 优化版本在启用超线程时测得的多线程浮点吞吐量低于禁用时的多线程浮点吞吐量。这是在 Ivy Bridge i7 (3770k) 上进行的。我还注意到,禁用超线程后,LINPACK 会导致更高的核心温度,尽管我 运行 CPU 处于较低的核心电压。所有这些让我相信,如果没有超线程,管道利用率实际上会更高。
我很好奇:这是否只是 LINPACK 算法的固有部分导致流水线停顿或 SMT 分配效率低下,或者当两个线程都发出宽 SIMD 指令时,英特尔的 SMT 实现是否合理地在安排流水线时遇到了麻烦?如果是这样,那是 Haswell 已经解决的问题,还是将在未来的英特尔架构中解决?这是AVX512容易出现的问题吗?
最后,在使用面向英特尔系统的 AVX 进行编程时,是否可以采取任何好的步骤来避免使用 SMT 进行低效的流水线分配?
超线程在两个硬件线程之间共享乱序执行资源,而不是将它们全部交给一个线程。通常情况下,如果一个线程已经可以保持管道满载,那么最坏的情况是您不会看到任何加速。无论哪种方式,执行单元应该咀嚼 4 微指令/时钟需要 运行。
如果每个线程都在自己的内存块上工作,那么 CPU 内核会尝试同时处理更多实时数据。 L1 / L2 缓存的竞争共享意味着这最终可能比没有 HT 更糟糕。
此外,一些工作负载有并行化的开销。只有令人尴尬的并行问题(比如做很多独立的 matmuls,而不是并行化一个大的)在协调线程方面的开销可以忽略不计。
正如 Agner Fog 在他的 Optimizing Assembly 手册中提到的那样,如果任何竞争共享或分区的 CPU 资源成为瓶颈,超线程将无济于事,而且可能会造成伤害。当代码在分支预测错误或缓存未命中上花费大量时间时,这是极好的,因为另一个线程可以防止饥饿的管道闲置。
矩阵数学具有足够可预测的访问模式,因此缓存未命中和预测错误的情况很少见。 (特别是在为缓存大小而被仔细阻止的代码中。)
如何避免 HT 无济于事:让您的代码变慢,因此单个线程无法有效地执行它以保持管道满载。 >.<.不过说真的,如果有一种算法在缓存未命中或分支预测错误方面与蛮力方法相比性能相同,那么使用它可能会有所帮助。例如考虑到分支在单个线程上错误预测的开销,对早期输出的测试可能几乎是一次清洗,但是当您的代码 运行ning 在同一核心的两个硬件线程上时,可能会快得多,所以蛮力-力道处于劣势
在进行超频和 运行 烧录测试时,我注意到 LINPACK 的 AVX 优化版本在启用超线程时测得的多线程浮点吞吐量低于禁用时的多线程浮点吞吐量。这是在 Ivy Bridge i7 (3770k) 上进行的。我还注意到,禁用超线程后,LINPACK 会导致更高的核心温度,尽管我 运行 CPU 处于较低的核心电压。所有这些让我相信,如果没有超线程,管道利用率实际上会更高。
我很好奇:这是否只是 LINPACK 算法的固有部分导致流水线停顿或 SMT 分配效率低下,或者当两个线程都发出宽 SIMD 指令时,英特尔的 SMT 实现是否合理地在安排流水线时遇到了麻烦?如果是这样,那是 Haswell 已经解决的问题,还是将在未来的英特尔架构中解决?这是AVX512容易出现的问题吗?
最后,在使用面向英特尔系统的 AVX 进行编程时,是否可以采取任何好的步骤来避免使用 SMT 进行低效的流水线分配?
超线程在两个硬件线程之间共享乱序执行资源,而不是将它们全部交给一个线程。通常情况下,如果一个线程已经可以保持管道满载,那么最坏的情况是您不会看到任何加速。无论哪种方式,执行单元应该咀嚼 4 微指令/时钟需要 运行。
如果每个线程都在自己的内存块上工作,那么 CPU 内核会尝试同时处理更多实时数据。 L1 / L2 缓存的竞争共享意味着这最终可能比没有 HT 更糟糕。
此外,一些工作负载有并行化的开销。只有令人尴尬的并行问题(比如做很多独立的 matmuls,而不是并行化一个大的)在协调线程方面的开销可以忽略不计。
正如 Agner Fog 在他的 Optimizing Assembly 手册中提到的那样,如果任何竞争共享或分区的 CPU 资源成为瓶颈,超线程将无济于事,而且可能会造成伤害。当代码在分支预测错误或缓存未命中上花费大量时间时,这是极好的,因为另一个线程可以防止饥饿的管道闲置。
矩阵数学具有足够可预测的访问模式,因此缓存未命中和预测错误的情况很少见。 (特别是在为缓存大小而被仔细阻止的代码中。)
如何避免 HT 无济于事:让您的代码变慢,因此单个线程无法有效地执行它以保持管道满载。 >.<.不过说真的,如果有一种算法在缓存未命中或分支预测错误方面与蛮力方法相比性能相同,那么使用它可能会有所帮助。例如考虑到分支在单个线程上错误预测的开销,对早期输出的测试可能几乎是一次清洗,但是当您的代码 运行ning 在同一核心的两个硬件线程上时,可能会快得多,所以蛮力-力道处于劣势