Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将比较例程转换为英特尔SIMD_C_X86_Intel_Sse_Simd - Fatal编程技术网

C 将比较例程转换为英特尔SIMD

C 将比较例程转换为英特尔SIMD,c,x86,intel,sse,simd,C,X86,Intel,Sse,Simd,我有一个例行程序,它应该测试一个浮点数是否小于零。如果是,我应该存储符号,我得到的是绝对值 int sign = 1; if (x < 0) { sign = -1; } x = fabs(x); int符号=1; if(x假设输入值在向量中,M128V: __m128 vmask = _mm_set1_ps(-0.0f); // create sign bit mask __m128 vsign = _mm_and_ps(v, vmask); // create

我有一个例行程序,它应该测试一个浮点数是否小于零。如果是,我应该存储符号,我得到的是绝对值

int sign = 1;
if (x < 0)
{
    sign = -1;
}
x = fabs(x);
int符号=1;
if(x<0)
{
符号=-1;
}
x=fabs(x);

我查看了英特尔SIMD内部函数,发现这条指令
dst=_-mm\u-cmplt\u-ps(a,b)
,它生成一个包含(0xffffff表示真)或(0表示假)的向量,但我被卡在那里;我如何知道
dst
向量的哪个元素是负的,或者不构建
符号向量

假设您的输入值在向量中
\uuu m128 v

__m128 vmask = _mm_set1_ps(-0.0f);      // create sign bit mask
__m128 vsign = _mm_and_ps(v, vmask);    // create vector of sign bits (MSB)
__m128i vsigni = _mm_add_epi32(_mm_srai_epi32((__m128i)vsign, 30), _mm_set1_epi32(1));
                                        // convert sign bits to integer +1/-1 (if needed (*))
v = _mm_andnot_ps(vmask, v);            // clear sign bits in v (i.e. v = fabsf(v))

(*)而不是浪费循环生成符号+ 1 / - 1,考虑是否可以直接使用符号位,省略这一步。

< P>假设输入值在向量<代码>中,M128V:

__m128 vmask = _mm_set1_ps(-0.0f);      // create sign bit mask
__m128 vsign = _mm_and_ps(v, vmask);    // create vector of sign bits (MSB)
__m128i vsigni = _mm_add_epi32(_mm_srai_epi32((__m128i)vsign, 30), _mm_set1_epi32(1));
                                        // convert sign bits to integer +1/-1 (if needed (*))
v = _mm_andnot_ps(vmask, v);            // clear sign bits in v (i.e. v = fabsf(v))

(*)而不是浪费循环生成符号+ 1 / - 1,考虑是否可以直接使用符号位,省略这个步骤。

< P>一个小的异常(x==+0.0f),可以使用指令<代码>符号< /> >生成整数掩码:

_mm_sign_epi32(_mm_set1_epi32(1), x)
这将取反1,如果x有一个小异常(x==+0.0f),您可以使用指令
符号生成整数掩码

_mm_sign_epi32(_mm_set1_epi32(1), x)

这将否定1,如果x在这之后如何处理
符号
?您确定需要2的补码整数
-1
/
+1
而不是
-1
/0或其他什么吗?还有,
x在那之后你用
sign
做什么?您确定需要2的补码整数
-1
/
+1
而不是
-1
/0或其他什么吗?此外,如果OP可以使用整数
0
/
-1
结果,则整数
pcmpgtd
对零可以测试符号位,作为右移的替代方案。或SSE4.1
blendps
在整数+1/-1位模式之间进行选择,但这在英特尔CPU上有额外的旁路延迟,在Haswell上端口5有2个UOP,因此可能会造成随机端口瓶颈。您可以避免
:直接在FP位模式上使用
srai
,然后用
\u mm\u或
而不是
\u mm\u add\u epi32
设置低位。这会将上面的31位保留为FP符号位的副本。(请注意,您假设可以将OP代码中的
-0.0
-NaN
视为小于
+0.0
,因此仅查看符号位与FP比较不同。)@PeterCordes:yes,所有优点——在我的脑海深处,我认为OP实际上可能只处理符号位,而不是浪费时间生成+1/-1值,因此在注释中使用了“如果需要”。不过,我应该在问题中记下这一点——我很快就会这么做。如果OP确实需要+1/-1作为符号,那么我喜欢你直接使用浮点的想法。如果OP可以使用整数
0
/
-1
结果,则整数
pcmpgtd
对零可以测试符号位,作为右移的替代方法。或SSE4.1
blendps
在整数+1/-1位模式之间进行选择,但这在英特尔CPU上有额外的旁路延迟,在Haswell上端口5有2个UOP,因此可能会造成随机端口瓶颈。您可以避免
:直接在FP位模式上使用
srai
,然后用
\u mm\u或
而不是
\u mm\u add\u epi32
设置低位。这会将上面的31位保留为FP符号位的副本。(请注意,您假设可以将OP代码中的
-0.0
-NaN
视为小于
+0.0
,因此仅查看符号位与FP比较不同。)@PeterCordes:yes,所有优点——在我的脑海深处,我认为OP实际上可能只处理符号位,而不是浪费时间生成+1/-1值,因此在注释中使用了“如果需要”。不过,我应该在问题中记下这一点——我很快就会这么做。如果OP确实需要+1/-1作为符号,那么我喜欢你直接对浮点进行srai的想法。
-NaN
是另一个例外,假设
x<0
是IEEE比较,其行为与问题中的代码不同。但是,如果OP真的需要+1/-1,并且不能仅仅求和比较结果,并在末尾或其他地方校正偏移量,那么这是一个好主意。
-NaN
是另一个例外,假设
x<0
是IEEE比较,其行为与问题中的代码不同。但是,是的,如果OP确实需要+1/-1,并且不能简单地求和比较结果,并在末尾更正偏移量或其他东西,那么这是个好主意。