在试图找出我的代码的内循环是否被击中硬件设计屏障或我的一部分屏障缺乏了解。还有更多一点吧,但我可以拿出来回答这个简单的问题如下:

如果我有以下代码:

float px[32768],py[32768],pz[32768];
float xref, yref, zref, deltax, deltay, deltaz;

initialize_with_random(px);
initialize_with_random(py);
initialize_with_random(pz);

for(i=0;i<32768-1;i++) {
  xref=px[i];
  yref=py[i];
  zref=pz[i];
  for(j=0;j<32768-1;j++ {
    deltx=xref-px[j];
    delty=yref-py[j];
    deltz=zref-pz[j];
  } }

我将能够在一个情况下,我有完全的控制权代码将SSE指令,看看什么类型的最大理论速度可达(装配,内联函数,等等),但在比结构中的其他(运行时环境无法控制,即它是一个多用户环境,所以我不能做任何事情的操作系统内核是如何分配时间,我的特别处理)。

现在,我看到3倍的速度了我的代码,当我会想到使用SSE会给我更多的载体深度大于3倍的速度向上的指示(可能是3倍的速度高达告诉我,我有一个4X最大理论吞吐量)。 (我试过的事情,如让deltx / delty / deltz是数组的情况下,编译器是不够聪明的自动推进当中,但我仍然只看到3倍速度的。)我使用的是英特尔的C编译器适当的编译器标记为矢量,但没有明显的内在函数

有帮助吗?

解决方案

它取决于CPU。但理论上的最大值不会得到上述4倍。我不知道一个CPU能够执行每时钟周期一个以上的SSE指令,这意味着它可以至多每个周期计算4个值。

大多数CPU的可以做的至少的一个浮动每个周期点标量指令,所以在这种情况下,你会看到一个4倍加速的理论最大值。

但是,你要回去看看你正在运行的CPU特定的指令吞吐量。

3×的实际加速是相当不错的,但。

其他提示

我想你也许不得不以某种方式交错内循环。三分量矢量是在一次得到完成,但是一次只有3操作。要到4,你会做,从第一向量3种成分,从1接下来,再用2和2,依此类推。如果你建立某种队列的加载和一次处理的数据4种成分,再经过分离,这也许工作。

修改:可以展开内环做每次迭代4个载体(假设数组大小始终是4的倍数)。这将完成我上面说的。

考虑:如何宽是浮法?有多宽SSEX指令?的比例应应该给你某种合理上限。

这也是值得注意的是乱序播放管道用的Havok获得加速的良好预期。

您应该考虑环平铺 - 你是在内部循环访问值的方式是可能造成大量颠簸的L1数据缓存。这不是太糟糕了,因为一切都可能仍然在L2为384 KB适合,但有容易的L1高速缓存命中和L2缓存命中之间的幅度差一个数量级,所以这样可以使你有很大的区别。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top