比较 AVX/AVX2 中的 2 个向量 (c)
Comparing 2 vectors in AVX/AVX2 (c)
我有两个 __m256i
向量(每个都包含字符),我想知道它们是否完全相同。如果所有位都相等,我只需要 true
,否则 0
。
最有效的方法是什么?这是加载数组的代码:
char * a1 = "abcdefhgabcdefhgabcdefhgabcdefhg";
__m256i r1 = _mm256_load_si256((__m256i *) a1);
char * a2 = "abcdefhgabcdefhgabcdefhgabcdefhg";
__m256i r2 = _mm256_load_si256((__m256i *) a2);
当前 Intel 和 AMD CPU 上最有效的方法是逐元素比较是否相等,然后检查所有元素的比较是否正确。
这会编译成多条指令,但它们都很便宜(如果你对结果进行分支)compare+branch 甚至宏融合成一个 uop。
#include <immintrin.h>
#include <stdbool.h>
bool vec_equal(__m256i a, __m256i b) {
__m256i pcmp = _mm256_cmpeq_epi32(a, b); // epi8 is fine too
unsigned bitmask = _mm256_movemask_epi8(pcmp);
return (bitmask == 0xffffffffU);
}
生成的 asm 应该是 vpcmpeqd / vpmovmskb / cmp 0xffffffff / je
,在 Intel CPU 上只有 3 微指令。
vptest
是 2 微指令并且不与 jcc
宏融合,因此等于或低于 movmsk
/ cmp
用于测试打包结果-比较。 (参见 http://agner.org/optimize/
我有两个 __m256i
向量(每个都包含字符),我想知道它们是否完全相同。如果所有位都相等,我只需要 true
,否则 0
。
最有效的方法是什么?这是加载数组的代码:
char * a1 = "abcdefhgabcdefhgabcdefhgabcdefhg";
__m256i r1 = _mm256_load_si256((__m256i *) a1);
char * a2 = "abcdefhgabcdefhgabcdefhgabcdefhg";
__m256i r2 = _mm256_load_si256((__m256i *) a2);
当前 Intel 和 AMD CPU 上最有效的方法是逐元素比较是否相等,然后检查所有元素的比较是否正确。
这会编译成多条指令,但它们都很便宜(如果你对结果进行分支)compare+branch 甚至宏融合成一个 uop。
#include <immintrin.h>
#include <stdbool.h>
bool vec_equal(__m256i a, __m256i b) {
__m256i pcmp = _mm256_cmpeq_epi32(a, b); // epi8 is fine too
unsigned bitmask = _mm256_movemask_epi8(pcmp);
return (bitmask == 0xffffffffU);
}
生成的 asm 应该是 vpcmpeqd / vpmovmskb / cmp 0xffffffff / je
,在 Intel CPU 上只有 3 微指令。
vptest
是 2 微指令并且不与 jcc
宏融合,因此等于或低于 movmsk
/ cmp
用于测试打包结果-比较。 (参见 http://agner.org/optimize/