我遇到了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
都不等于零。
更新
在评论讨论后,我的问题得到了解决,但我对函数_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
我认为只有第一个是正确的。那么为什么这个函数产生不同的输出呢?
答案 0 :(得分:4)
_mm256_testc_pd
仅对每个双精度元素的符号位进行操作,因此观察到的行为是正确的。如果要在每个元素中测试双精度值,请先使用合适的比较指令(例如_mm256_cmp_pd
和_CMP_xxx
参数),然后使用_mm256_testc_pd
或_mm256_testz_pd
之后,视您的具体要求而定。
答案 1 :(得分:0)
感谢Peter Cordes和其他所有人,我的问题的正确(和最美)解决方案是
res = _mm256_testz_si256(_mm256_castpd_si256(a), _mm256_castpd_si256(a))