以下两行代码有什么区别?
__m128 x = _mm_load_ps((float *) ptr);
__m128 y = _mm_load_pd((double *)ptr);
换句话说,为什么会有这么多不同的_mm_load_xyz
指令,而不是一个通用的__m128 _mm_load(const void *)
指令呢?
不同的内在功能因为它们对应不同的指令。
不同的加载指令是因为英特尔希望保持设计处理器的自由,使双精度向量由不同的物理寄存器文件支持,而单精度向量或整数向量则可能使用不同的执行单元。如果没有一种方法指定数据应该被加载到适当的寄存器文件或转发网络中,则任何这些操作都可能增加额外的延迟。
想一种方式来思考这个问题,不同的指令做“相同的事情”,但同时提供了一个提示给处理器,告诉它正在加载的数据将如何被未来的指令使用。这可以帮助处理器确保数据在正确的位置,以尽可能高效地使用,或者可能会被处理器忽略。
请注意,这不仅仅是一种假设。存在这样一种处理器,使用整数向量加载(MOVDQA)来加载由浮点操作使用的数据比使用浮点加载获取浮点操作的数据需要更长的时间(反之亦然)。有关此主题的更多详细信息,请参见Intel Optimization Manual或Agner Fog的笔记。使用与您将如何使用数据匹配的加载方式,以避免未来出现这样的性能风险。
_mm_load_ps
加载4个单精度浮点数值。
_mm_load_pd
加载2个双精度浮点数值。
这两个函数功能不同,因此有必要使用不同的函数。另外,在C语言中,没有重载的概念。
_mm_load_pd
的返回类型是__m128d
,而不是__m128
。 - Paul R