MMX 与 SSE2 性能比较
Posted
技术标签:
【中文标题】MMX 与 SSE2 性能比较【英文标题】:MMX v/s SSE2 Performance Comparison 【发布时间】:2013-03-31 18:31:03 【问题描述】:问题:
我将 MMX 代码转换为相应的 SSE2 代码。我预计几乎 1.5x-2x 的加速。但两者都花费了完全相同的时间。为什么会这样?
场景:
我正在学习 SIMD 指令集及其性能比较。我进行了一个数组操作,使得 Z = X^2 + Y^2
其中 X 和 Y 是 "char" 类型的大型一维数组。 X 和 Y 的值被限制为 小于 10,因此 Z 始终为 。 (不用担心任何溢出)。
我先写了它的 C++ 代码,检查了它的时间。然后编写相应的汇编代码(~3x 加速)。然后我编写了它的 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 - 我浏览了英特尔和其他网站的一些优化手册。 SSE2 代码的主要问题是 16 _memory 对齐。当我手动检查地址时,发现它们都是 16 _memory 对齐的。但我同时使用了 MOVDQU 和 MOVDQA,但两者的结果相同,并且与 MMX 相比没有加速。
2 - 我进入调试模式并检查每个寄存器值并执行指令。它们的执行与我想的完全一样,即占用 16 个字节并输出 16 个字节。
资源:
我在 Windows 7 和 Visual C++ 2010 中使用 Intel Core i5 处理器。
问题:
所以最后一个问题是,为什么 SSE2 代码与 MMX 代码相比没有性能提升?我在 SSE 代码中做错了吗?还是有其他解释?
【问题讨论】:
您的 SSE 代码中有一个emms
,但这不应该是造成这种情况的原因。你的数组有多长?
@harold:数组很大,大小 = 100000000 字节。我把它放大了看时间。否则它会在 0 时间发生。
这是个问题。这比缓存大得多,因此瓶颈是主内存吞吐量。
你能再解释一下吗?
该数组甚至几乎无法放入缓存中,因此它必须来自主内存。那很慢。显然比你正在做的计算要慢,这并不奇怪。我建议您更改数组,使它们至少都适合 L3,然后在必要时在同一个数组上运行多次基准测试。
【参考方案1】:
Harold 的评论完全正确。您正在处理的数组不适合您机器上的缓存,因此您的计算完全受负载存储限制。
我为您在当前一代 i7 上针对各种缓冲区长度的计算吞吐量计时,以及除加载和存储移除之外的所有内容的同一例程的吞吐量:
我们在这里观察到的是,一旦缓冲区变得如此之大以至于超出了 L3 缓存,您的计算吞吐量就会与实现的加载/存储带宽完全匹配。这告诉我们如何处理数据基本上没有区别(除非你让它显着变慢);计算速度受限于处理器将数据移入/移出内存的能力。
如果您对较小的数组进行计时,您会发现两种实现之间的差异。
【讨论】:
是的,你是对的。我将数组更改为 1MB 大小,现在有所不同。但又是一个问题,现在我的 SSE2 代码比 MMX 快3-5x
。有可能吗?我认为它应该接近 2 倍。 (我在同一个文件中一个接一个地调用 C++、MMX 和 SSE。所以会不会有缓存效应?)
还有一个问题,在你的非常高数据的图中,算术运算变得等于加载/存储操作。这是为什么呢?
不错的图,你用什么工具制作的?
@Cameron:OS X 上的数字,没什么花哨的。以上是关于MMX 与 SSE2 性能比较的主要内容,如果未能解决你的问题,请参考以下文章