我在程序中执行的常见操作是通过标量缩放矢量(V*s,例如[1,2,3,4]*2 == [2,4,6,8]).是否有SSE(或AVX)指令执行此操作,除了首先在向量中的每个位置加载标量(例如_mm_set_ps(2,2,2,2))然后乘以?
这就是我现在所做的:
__m128 _scalar = _mm_set_ps(s,s,s,s);
__m128 _result = _mm_mul_ps(_vector, _scalar);
Run Code Online (Sandbox Code Playgroud)
我正在寻找像......
__m128 _result = _mm_scale_ps(_vector, s);
Run Code Online (Sandbox Code Playgroud)
Pau*_*l R 14
根据您的编译器,您可以使用_mm_set1_ps以下方法稍微改进代码生成:
const __m128 scalar = _mm_set1_ps(s);
__m128 result = _mm_mul_ps(vector, scalar);
Run Code Online (Sandbox Code Playgroud)
但是,像这样的标量常量只需要在任何循环之外初始化一次,因此性能成本应该是无关紧要的.(除非标量值在循环内发生变化?)
与往常一样,您应该查看编译器生成的代码,并尝试在合适的分析器下运行代码以查看热点的真正位置.
没有将向量乘以标量的指令。然而,有一些指令用于将相同的标量值加载到向量寄存器中的所有位置。
AVX指令集提供_mm_broadcast_ss/ _mm256_broadcast_ss/_mm256_broadcast_sd内在具有相同浮动/双值填充SSE和AVX寄存器。
在 SSE3 指令集中,您可能会发现_mm_loaddup_pd使用相同的双精度值填充 SSE 寄存器的内在函数。
在SSE的其他版本通常是最好的选择是使用加载一个标量值_mm_load_ss/_mm_load_sd然后将其复制成与向量寄存器中的所有元素_mm_shuffle_ps/ _mm_unpacklo_pd。