c 11 – 将uint8_t位图最佳化为8 x 32位SIMD“bool”向量
发布时间:2020-12-16 09:56:39 所属栏目:百科 来源:网络整理
导读:作为压缩算法的一部分,我正在寻找实现以下目标的最佳方法: 我在uint8_t中有一个简单的位图.例如01010011 我想要的是形式的__m256i:(0,maxint,maxint) 实现此目的的一种方法是将8 x maxint的向量混合到零向量中.但这首先要求我将uint8_t扩展到正确的shuffle
作为压缩算法的一部分,我正在寻找实现以下目标的最佳方法:
我在uint8_t中有一个简单的位图.例如01010011 我想要的是形式的__m256i:(0,maxint,maxint) 实现此目的的一种方法是将8 x maxint的向量混合到零向量中.但这首先要求我将uint8_t扩展到正确的shuffle位图. 我想知道是否有更好的方法? 解决方法
基于这个问题
fastest-way-to-broadcast-32-bits-in-32-bytes的变体,这是一个解决方案(PaulR改进了我的解决方案,看到我的答案的结尾或他的答案).
__m256i t1 = _mm256_set1_epi8(x); __m256i t2 = _mm256_and_si256(t1,mask); __m256i t4 = _mm256_cmpeq_epi32(t2,_mm256_setzero_si256()); t4 = _mm256_xor_si256(t4,_mm256_set1_epi32(-1)); 我现在没有AVX2硬件来测试这个,但这里有一个SSE2版本,显示它的工作原理,同时也展示了如何定义掩码. #include <x86intrin.h> #include <stdint.h> #include <stdio.h> int main(void) { char mask[32] = { 0x01,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x80,}; __m128i mask1 = _mm_loadu_si128((__m128i*)&mask[ 0]); __m128i mask2 = _mm_loadu_si128((__m128i*)&mask[16]); uint8_t x = 0x53; //0101 0011 __m128i t1 = _mm_set1_epi8(x); __m128i t2 = _mm_and_si128(t1,mask1); __m128i t3 = _mm_and_si128(t1,mask2); __m128i t4 = _mm_cmpeq_epi32(t2,_mm_setzero_si128()); __m128i t5 = _mm_cmpeq_epi32(t3,_mm_setzero_si128()); t4 = _mm_xor_si128(t4,_mm_set1_epi32(-1)); t5 = _mm_xor_si128(t5,_mm_set1_epi32(-1)); int o1[4],o2[4]; _mm_store_si128((__m128i*)o1,t4); _mm_store_si128((__m128i*)o2,t5); for(int i=0; i<4; i++) printf("%d n",o1[i]); for(int i=0; i<4; i++) printf("%d n",o2[i]); } 编辑: PaulR改进了我的解决方案 __m256i v = _mm256_set1_epi8(u); v = _mm256_and_si256(v,mask); v = _mm256_xor_si256(v,mask); return _mm256_cmpeq_epi32(v,_mm256_setzero_si256()); 掩码定义为 int mask[8] = { 0x01010101,0x02020202,0x04040404,0x08080808,0x10101010,0x20202020,0x40404040,0x80808080,}; 有关详细信息,请参阅性能测试的答案. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |