【发布时间】:2015-08-23 16:12:16
【问题描述】:
我正在为 3 值水平和编写一个函数,编译器生成次优代码。该算法的工作原理如下:(a,b,c 是值,_ 无关紧要)
a b c _ --movhlps-> a b _ _ --shufps-> a _ _ _
c _ _ _ b _ _ _
c _ _ _
后跟两个addps。
但是当我用内在函数编写代码时,我无法让它生成忽略其他元素值的程序集。
显而易见的事情,
__m128 sum3_a(__m128 r)
{
__m128 b = _mm_movehl_ps(__m128(), r);
//...
生成
sum3_a(float __vector(4)):
xorpd %xmm2, %xmm2
movapd %xmm0, %xmm3
unpckhpd %xmm2, %xmm3 # xmm3 = xmm3[1],xmm2[1]
所以看起来_mm128() 生成了一个用零填充的寄存器(xorpd)。
我可以像这样摆脱xorpd,
__m128 sum3_b(__m128 r)
{
__m128 b = _mm_movehl_ps(r, r);
//...
但这给了我(公平地说,正是我所要求的),
sum3_b(float __vector(4)):
movaps %xmm0, %xmm2
movhlps %xmm2, %xmm2 # xmm2 = xmm2[1,1]
但我想要的只是
sum3(float __vector(4)):
movhlps %xmm2, %xmm0
如何用 C++ 编写?
【问题讨论】:
-
好吧,对于
__m128(),您要求 零(或默认值,取决于 C++ 版本——但是在非具有隐式默认构造函数的类类型)初始化。所以它被初始化为零也就不足为奇了。只需创建一个局部变量而不初始化它,如果这是你想要的? -
@Damon 这似乎生成与使用相同变量两次调用它相同的代码。
-
基本上,你不会。无论如何,reg-reg 移动几乎是免费的,所以还不错。
-
@Damon:我试过了(使用 gcc -O3,而不是 g++):
__m128 b = _mm_movehl_ps(b, r);产生一个pxor来初始化tmp。
标签: c++ sse intrinsics