后续问题:如何使用 avx2 计算单个位

问题描述

这是一个函数,它接受一个 64 位整数数组并计算每个位置有多少 1 位。使用 AVX2,应该可以同时对 16 位执行此操作,但是每个计数器最多只能达到 65536。以下代码将计算 65500 个值的每个块,但我错过了一个关键操作:我找不到方法将每个数字单独移动不同的计数。我错过了什么吗?代码中的注释显示了该位置。理想情况下,每个数字都从内存中加载,并分成 4 个 16 位块。每个块都可以在一个 256 位寄存器上处理。为了计数超过 64k,计数将存储在内存中并添加到更宽的寄存器中。

void countHistBits4(const uint64_t p[],uint32_t n,uint32_t hist[64]) {
  uint16_t shifts[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
  uint16_t maskss[16] = {1,1};
    __m256i shift = _mm256_load_si256((__m256*)shifts);
        __m256i mask1 = _mm256_load_si256((__m256*)masks);
        for (uint32_t j = 0; j < n; j += 65500) {
            __m256i count1 = _mm256_setzero_si256();
            __m256i count2 = _mm256_setzero_si256();
            __m256i count3 = _mm256_setzero_si256();
            __m256i count4 = _mm256_setzero_si256();
            for (uint32_t i = 0; i < 65500; i++) {
                __m256i v1 = _mm256_set1_epi16(p[i] & 0xFFFF);
                __m256i v2 = _mm256_set1_epi16((p[i] >> 16) & 0xFFFF);
                __m256i v3 = _mm256_set1_epi16((p[i] >> 32) & 0xFFFF);
                __m256i v4 = _mm256_set1_epi16((p[i] >> 48) & 0xFFFF);

                // for each bit,right shift to the 1 position,and with 1
                // and add to the count
                
                // this isn't right. How to shift each 16 bit value by different const?
                // if that isn't possible,what is the approach?
                v1 = _mm256_srl_epi16(v1,shift);
                v2 = _mm256_srl_epi16(v2,shift);
                v3 = _mm256_srl_epi16(v3,shift);
                v4 = _mm256_srl_epi16(v4,shift);
                v1 = _mm256_and_si256(v1,mask1);
                count1 = _mm256_adds_epi16 (count1,v1);
                v2 = _mm256_and_si256(v2,mask1);
                count2 = _mm256_adds_epi16 (count2,v2);
                v3 = _mm256_and_si256(v3,mask1);
                count3 = _mm256_adds_epi16 (count3,v3);
                v4 = _mm256_and_si256(v4,mask1);
                count4 = _mm256_adds_epi16 (count4,v4);
            }
            // store and add into larger counters... 
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)