c++ - 转置 4x4 字节矩阵的最快方法

标签 c++ c optimization matrix bit-manipulation

我有一个 4x4 字节 block ,我想使用通用硬件进行转置。换句话说,对于字节 A-P,我正在寻找最有效(就指令数量而言)的方式

A B C D
E F G H
I J K L
M N O P

A E I M
B F J N
C G K O
D H L P

我们可以假设我有指向 AEIM 的有效指针内存(这样从 A 读取 32 位将得到包含字节 ABCD 的整数)。

这不是 this question 的拷贝因为大小和数据类型的限制。我的矩阵的每一行都可以放入一个 32 位整数,我正在寻找可以使用通用硬件快速执行转置的答案,类似于 SSE 宏 _MM_TRANSPOSE4_PS 的实现。

最佳答案

您想要适​​饮性和效率。好吧,你不能两者兼得。你说你想用最少的指令来做到这一点。好吧,使用 x86 指令集中的 pshufb 指令(见下文),仅使用 SSE3 的一条指令就可以做到这一点。

也许 ARM Neon 有类似的东西。如果你想要效率(并且确定你需要它)那么学习硬件。

字节的 _MM_TRANSPOSE4_PS 的 SSE 等价物是使用带有掩码的 _mm_shuffle_epi8(pshufb 的内在函数)。在主循环之外定义掩码。

//use -msse3 with GCC or /arch:SSE2 with MSVC
#include <stdio.h>
#include <tmmintrin.h> //SSSE3
int main() {
    char x[] = {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,15,16};
    __m128i mask = _mm_setr_epi8(0x0,0x04,0x08,0x0c, 0x01,0x05,0x09,0x0d, 0x02,0x06,0x0a,0x0e, 0x03,0x07,0x0b,0x0f);

    __m128i v = _mm_loadu_si128((__m128i*)x);
    v = _mm_shuffle_epi8(v,mask);
    _mm_storeu_si128((__m128i*)x,v);
    for(int i=0; i<16; i++) printf("%d ", x[i]); printf("\n");
    //output: 0 4 8 12 1 5 9 13 2 6 10 15 3 7 11 16   
}

关于c++ - 转置 4x4 字节矩阵的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24816728/

相关文章:

c++ - 拦截并忽略 QTabWidget 中的滚轮事件

c++ - 在宏定义中使用 __LINE__

c - sizeof 运算符如何在 C 中工作?

c - 读一个C文件,多读一行,为什么?

c++ - 取消引用的列表迭代器段错误

c++ - 使用池分配器覆盖 'new';返回NULL?

c - 为什么 scanf() 函数不等待我在下面代码的最后输入 char

c - 为什么 n++ 比 n=n+1 执行得更快?

c# - 优化代码,使其执行得更快

c# - 使用 ExpertPDF/Aspose.Pdf 组件将 Html 转换为 PDF 需要很长时间