问题:
我将MMX转换成相应的SSE2代码。我预计会加速1.5倍-2倍。但两者的时间完全相同。为什么会这样呢?
场景:
我正在学习SIMD指令集及其性能比较。我使用了一个数组操作,其中X和Y是"char"类型的一维大数组。X和Y的值被限制为小于10,因此Z总是<255 (1字节)。(不用担心溢出)。
我首先编写了它的C++代码,检查了它的时间。然后编写相应的汇编代码(~3x加速比)。然后我编写了它的MMX代码(~12xv/s C++)。然后,我将MMX转换成SSE2代码,速度与MMX代码完全相同。从理论上讲,在SSE2中,我预计与MMX相比,它的加速比为2倍。
对于从MMX到SSE2的转换,我将所有mmx转换为xmm reg。然后换了几个动作指令等等。
我的MMX和SSE代码被粘贴在这里:https://gist.github.com/abidrahmank/5281486 (我不想把它们都粘贴在这里)
这些函数稍后从main.cpp文件中调用,其中数组作为参数传递。
我所做的:
我查阅了英特尔和其他网站的一些优化手册。SSE2码的主要问题是16 _memory对齐。当我手动检查地址时,发现它们都是16 _memory对齐的。但我同时使用了MOVDQU和MOVDQA,但与MMX相比,两者都给出了相同的结果并没有加速。
2-我进入调试模式,检查每个寄存器值,并执行指令。它们被执行与我想的完全一样,即16个字节被取下来,结果16个字节被输出。
资源:
我使用英特尔核心i5处理器与Windows 7和视觉C++ 2010。
问题:
因此,最后一个问题是,为什么SSE2代码与MMX代码相比没有任何性能改进?我在SSE代码中做错什么了吗?或者还有别的解释吗?
发布于 2013-04-01 01:33:06
Harold的评论是绝对正确的。您正在处理的数组不适合计算机上的缓存,因此您的计算完全是负载存储绑定。
我在当前生成的i7上为不同的缓冲区长度计时了计算的吞吐量,还为除已删除的负载和存储之外的所有东西设置了相同例程的吞吐量:

我们在这里观察到的是,一旦缓冲区变得如此大以至于超出了L3缓存,您的计算的吞吐量就与实现的负载/存储带宽完全匹配。这告诉我们,处理数据的方式本质上并没有什么区别(除非您使其慢得多);计算速度受到处理器将数据移动到/从内存的能力的限制。
如果您在较小的数组上执行计时,您将看到两个实现之间的差异。
https://stackoverflow.com/questions/15732942
复制相似问题