gpt4 book ai didi

assembly - 用于旋转或转置数组的最佳 SIMD 算法

转载 作者:行者123 更新时间:2023-12-02 21:26:53 26 4
gpt4 key购买 nike

我正在研究一个数据结构,其中有一个 16 uint64 数组。它们在内存中的布局如下(下面每个代表一个 int64):

A0 A1 A2 A3 B0 B1 B2 B3 C0 C1 C2 C3 D0 D1 D2 D3

期望的结果是将数组转置为:

A0 B0 C0 D0 A1 B1 C1 D1 A2 B2 C2 D2 A3 B3 C3 D3

将数组旋转 90 度也是 future 循环可接受的解决方案:

D0 C0 B0 A0 D1 C1 B1 A1 D2 C2 B2 A2 D3 C3 B3 A3

我需要这个,以便稍后快速操作箭头(用另一个 SIMD 行程顺序遍历它,一次 4 个)。

到目前为止,我已经尝试通过加载 A 的 4 x 64 位向量、对元素进行位掩码和混洗以及将其与 B 等进行“或”运算,然后对 C 重复此操作来“混合”数据...不幸的是,这是数组中每段 4 个元素的 5 x 4 SIMD 指令(一次加载、一次掩码、一次随机播放、一个或与下一个元素,最后一个存储)。看来我应该可以做得更好。

我有 AVX2 可用,并且我使用 clang 进行编译。

最佳答案

uint64_t A[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
__m256i row0 = _mm256_loadu_si256((__m256i*)&A[ 0]); //0 1 2 3
__m256i row1 = _mm256_loadu_si256((__m256i*)&A[ 4]); //4 5 6 7
__m256i row2 = _mm256_loadu_si256((__m256i*)&A[ 8]); //8 9 a b
__m256i row3 = _mm256_loadu_si256((__m256i*)&A[12]); //c d e f

我现在没有硬件来测试这个,但类似下面的东西应该可以满足你的要求

__m256i tmp3, tmp2, tmp1, tmp0;
tmp0 = _mm256_unpacklo_epi64(row0, row1); //0 4 2 6
tmp1 = _mm256_unpackhi_epi64(row0, row1); //1 5 3 7
tmp2 = _mm256_unpacklo_epi64(row2, row3); //8 c a e
tmp3 = _mm256_unpackhi_epi64(row2, row3); //9 d b f
//now select the appropriate 128-bit lanes
row0 = _mm256_permute2x128_si256(tmp0, tmp2, 0x20); //0 4 8 c
row1 = _mm256_permute2x128_si256(tmp1, tmp3, 0x20); //1 5 9 d
row2 = _mm256_permute2x128_si256(tmp0, tmp2, 0x31); //2 6 a e
row3 = _mm256_permute2x128_si256(tmp1, tmp3, 0x31); //3 7 b f

__m256i _mm256_permute2x128_si256 (__m256i a, __m256i b, const int imm)

intrinsic 从两个源选择 128 位 channel 。您可以在the Intel Intrinsic Guide中阅读相关内容。 。有一个版本 _mm256_permute2f128_si256 只需要 AVX 并作用于浮点域。我用它来检查我是否使用了正确的控制字。

关于assembly - 用于旋转或转置数组的最佳 SIMD 算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27013292/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com