问题:

我将MMX转换为相应的SSE2代码。我预计将提高1.5到2倍的速度。但是两者都花了完全相同的时间。为什么?

方案:

我正在学习SIMD指令集及其性能比较。我进行了一个数组操作,即 Z = X^2 + Y^2 ,其中X和Y是“char” 类型的大一维数组。 X和Y的值限制为小于10 ,因此Z始终为 。 (不用担心任何溢出)。

我首先编写了C++代码,检查了时间。然后编写相应的汇编代码(约3倍加速)。然后我写了它的MMX代码(〜12x v / s C++)。然后,我将MMX转换为SSE2代码,并且其速度与MMX代码完全相同。从理论上讲,在SSE2中,我期望速度比MMX快2倍。

为了从MMX转换为SSE2,我将所有mmx reg转换为xmm reg。然后更改了几个运动指令等。

我的MMX和SSE代码粘贴在这里: https://gist.github.com/abidrahmank/5281486
(我不想将它们全部粘贴在这里)

这些函数随后从main.cpp文件中调用,其中将数组作为参数传递。

我做了什么:

1-我仔细阅读了Intel和其他网站上的一些优化手册。 SSE2代码的主要问题是 16 _内存对齐。当我手动检查地址时,发现它们全部都是16 _memory对齐的。但是我同时使用了 MOVDQU MOVDQA ,但是与MMX相比,它们都提供了相同的结果,并且没有提速。

2-我进入 Debug模式,并检查已执行指令的每个寄存器值。它们的执行与我所想的完全相同,即占用16个字节并输出结果16个字节。

资源:

我正在Windows 7和Visual C++ 2010中使用Intel Core i5处理器。

问题:

所以最后一个问题是,与MMX代码相比,为什么SSE2代码没有性能改进?我在SSE代码中做错什么了吗?还是有其他解释吗?

最佳答案

Harold 的评论绝对正确。您正在处理的数组无法放入计算机的缓存中,因此您的计算完全受负载存储的约束。

我将当前计算的吞吐量定时用于各种缓冲长度的当前i7上,并且将相同例程的吞吐量定时,除了删除了负载和存储之外,其他所有操作:

我们在这里观察到的是,一旦缓冲区变得很大,以至于它不在L3高速缓存中,则计算的吞吐量将与所达到的加载/存储带宽完全匹配。这告诉我们,您如何处理数据基本上没有什么区别(除非您使数据处理速度大大降低);计算速度受到处理器将数据移入/移出内存的能力的限制。

如果对较小的阵列进行计时,则会发现两种实现方式之间存在差异。

07-28 06:54