【发布时间】:2015-08-18 12:15:38
【问题描述】:
我遇到了 AVX 内部指令 _mm256_testc_pd() 的一个非常奇怪的行为。 这里可以看到这个函数的描述https://software.intel.com/sites/landingpage/IntrinsicsGuide/#techs=AVX,AVX2&text=test&expand=5432
我在我的代码中使用了 2 次,预计会看到与零寄存器进行比较的类似结果。
#include <immintrin.h>
#include <stdio.h>
int main(void)
{
unsigned char arr[32] __attribute__ ((aligned (32)));
__m256d a, zero;
int res1, res2;
memset(arr, 0 , 32);
arr[0] = 0xff;
arr[4] = 0xff;
arr[8] = 0xff;
arr[12] = 0xff;
arr[16] = 0xff;
arr[20] = 0xfd;
arr[24] = 0xff;
arr[28] = 0xff;
zero = _mm256_setzero_pd();
a = _mm256_load_pd((double *)arr);
res1 = _mm256_testc_pd(zero, a);
printf("res1 = %d\n" , res1);
memset(arr, 0xff, 32);
a = _mm256_load_pd((double *)arr);
res2 = _mm256_testc_pd(zero, a);
printf("res2 = %d\n" , res2);
return 0;
}
结果我得到了
res1 = 1
res2 = 0
有人知道为什么会这样吗?我认为在这两种情况下a 都不等于零。
更新
在 cmets 讨论后,我的问题得到了解决,但我对函数 _mm256_testc_si256 和 _mm256_testz_si256 有一点误解
例如:
unsigned char arr[32] __attribute__ ((aligned (32)));
__m256d a, zero;
int res1, res2;
memset(arr, 0 , 32);
arr[0] = 0x80;
zero = _mm256_setzero_pd();
a = _mm256_load_pd((double *)arr);
res1 = _mm256_testc_si256(_mm256_castpd_si256(zero),_mm256_castpd_si256(a));
res2 = _mm256_testz_si256(_mm256_castpd_si256(zero),_mm256_castpd_si256(a));
printf("res1 = %d\n" , res1);
printf("res2 = %d\n" , res2);
输出是
res1 = 0
res2 = 1
而且我认为只有第一个是正确的。那么为什么这个函数会产生不同的输出呢?
【问题讨论】:
-
arr[20] = 0xfd;是故意的吗? -
没关系,可能是
0xff,同样的行为。 -
这条指令真的能如你所愿吗?我宁愿说你想使用 _mm256_cmp_pd() 来比较值。
-
我认为你是对的,但你知道 _mm256_cmp_pd () 的第三个参数应该是什么吗?
-
@AlekseyM:你可以通过
_CMP_EQ_OQ(==0)。