在英特尔x86 ISA上,_mm_load_ps vs. _mm_load_pd等的区别是什么?

16

以下两行代码有什么区别?

__m128 x = _mm_load_ps((float *) ptr);
__m128 y = _mm_load_pd((double *)ptr);

换句话说,为什么会有这么多不同的_mm_load_xyz指令,而不是一个通用的__m128 _mm_load(const void *)指令呢?


4
_mm_load_pd 的返回类型是 __m128d,而不是 __m128 - Paul R
1
@PaulR:那真是合乎情理。我完全没有注意到。谢谢你指出来。 :) - user541686
2个回答

16

不同的内在功能因为它们对应不同的指令。

不同的加载指令是因为英特尔希望保持设计处理器的自由,使双精度向量由不同的物理寄存器文件支持,而单精度向量或整数向量则可能使用不同的执行单元。如果没有一种方法指定数据应该被加载到适当的寄存器文件或转发网络中,则任何这些操作都可能增加额外的延迟。

想一种方式来思考这个问题,不同的指令做“相同的事情”,但同时提供了一个提示给处理器,告诉它正在加载的数据将如何被未来的指令使用。这可以帮助处理器确保数据在正确的位置,以尽可能高效地使用,或者可能会被处理器忽略。

请注意,这不仅仅是一种假设。存在这样一种处理器,使用整数向量加载(MOVDQA)来加载由浮点操作使用的数据比使用浮点加载获取浮点操作的数据需要更长的时间(反之亦然)。有关此主题的更多详细信息,请参见Intel Optimization Manual或Agner Fog的笔记。使用与您将如何使用数据匹配的加载方式,以避免未来出现这样的性能风险。


哎呀,没关系,我错了——返回类型是不同的。现在完全有意义了。 :) +1 非常感谢。 - user541686
@Mehrdad 这与你昨天在SSE问题中提到的同一域名重排有关。 - Mysticial

5

_mm_load_ps 加载4个单精度浮点数值。

_mm_load_pd 加载2个双精度浮点数值。

这两个函数功能不同,因此有必要使用不同的函数。另外,在C语言中,没有重载的概念。


比我的解释更好 :) - Jesus Ramos
@Mehrdad,嗯,既然我们在使用intrinsic编程,那么这些函数的实现可能会有所不同,无法实现泛化。 - Tony The Lion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接