6

Background

I have an EP (Embarassingly Parallell) C application running four threads on my laptop which contains an intel i5 M 480 running at 2.67GHz. This CPU has two hyperthreaded cores.

The four threads execute the same code on different subsets of data. The code and data have no problems fitting in a few cache lines (fit entirely in L1 with room to spare). The code contains no divisions, is essentially CPU-bound, uses all available registers and does a few memory accesses (outside L1) to write results on completion of the sequence.

The compiler is mingw64 4.8.1 i e fairly recent. The best basic optimization level appears to be -O1 which results in four threads that complete faster than two. -O2 and higher run slower (two threads complete faster than four but slower than -O1) as does -Os. Every thread on average does 3.37 million sequences every second which comes out to about 780 clock cycles for each. On average every sequence performs 25.5 sub-operations or one per 30.6 cycles.

So what two hyperthreads do in parallell in 30.6 cycles one thread will do sequentially in 35-40 or 17.5-20 cycles each.

Where I am

I think what I need is generated code which isn't so dense/efficient that the two hyperthreads constantly collide over the local CPU's resources.

These switches work fairly well (when compiling module by module)

-O1 -m64 -mthreads -g -Wall -c -fschedule-insns

as do these when compiling one module which #includes all the others

-O1 -m64 -mthreads -fschedule-insns -march=native -g -Wall -c -fwhole-program

there is no discernible performance difference between the two.

Question

Has anyone experimented with this and achieved good results?

4

4 回答 4

1

你说“我认为我需要的是生成的代码不是那么密集/高效,以至于两个超线程不断地在本地 CPU 的资源上发生冲突。”。那是相当误导的。

你的 CPU 有一定数量的资源。代码将能够使用一些资源,但通常不是全部。超线程意味着您有两个能够使用资源的线程,因此将使用更高百分比的这些资源。

您想要的是最大化使用的资源百分比。高效的代码首先会更有效地使用这些资源,而添加超线程只会有所帮助。您不会通过超线程获得那么多的加速,但那是因为您已经在单线程代码中获得了加速,因为它更有效。如果你想吹嘘超线程给你带来了很大的加速,当然,从低效的代码开始。如果您想要最大速度,请从高效的代码开始。

现在,如果您的代码受到延迟的限制,这意味着它可以执行很多无用的指令而不会受到惩罚。使用超线程,这些无用的指令实际上是有代价的。因此,对于超线程,您希望最大限度地减少指令的数量,尤其是那些被延迟隐藏并且在单线程代码中没有可见成本的指令。

于 2014-04-09T09:49:21.687 回答
1

您可以尝试使用处理器关联将每个线程锁定到一个核心。我听说这可以通过一些代码为您提高 15%-50% 的效率。节省的是,当处理器上下文切换发生时,缓存等中的变化较少。这在刚刚运行您的应用程序的机器上会更好地工作。

于 2014-04-09T10:17:19.847 回答
0

超线程可能会适得其反。碰巧的是,计算密集型负载通常会适得其反。

我会尝试:

  • 在 BIOS 级别禁用它并运行两个线程
  • 尝试优化和使用向量 SSE/AVX 扩展,最终甚至手动

解释:HT 很有用,因为硬件线程比软件线程更有效地调度。但是,两者都有开销。调度 2 个线程比调度 4 个更轻量级,如果您的代码已经“密集”,我会尝试进行“更密集”执行,尽可能优化 2 个管道上的执行。

很明显,如果你优化得更少,它的扩展性会更好,但难度会更快。因此,如果您正在寻找更高的可扩展性 - 这个答案不适合您......但如果您正在寻找更快的速度 - 试试看。

正如其他人已经说过的,优化时没有通用的解决方案,否则这个解决方案应该已经嵌入到编译器中。

于 2014-04-09T10:25:23.520 回答
0

您可以下载 OpenCL 或 CUDA 工具包并为您的显卡实现一个版本……您也许可以毫不费力地将其加速 100 倍。

于 2014-04-09T15:59:07.127 回答