我有一个矩阵(相对较大),我需要转置.例如假设我的矩阵是
a b c d e f
g h i j k l
m n o p q r
Run Code Online (Sandbox Code Playgroud)
我希望结果如下:
a g m
b h n
c I o
d j p
e k q
f l r
Run Code Online (Sandbox Code Playgroud)
最快的方法是什么?
我发现这个职位,说明如何进行转一个8x8矩阵的字节24点的操作,和几个卷轴后有代码实现转置.但是,这种方法没有利用我们可以阻止 8x8转置为4个4x4转置的事实,并且每个转换只能在一个shuffle指令中完成(这篇文章是参考文献).所以我推出了这个解决方案:
__m128i transpose4x4mask = _mm_set_epi8(15, 11, 7, 3, 14, 10, 6, 2, 13, 9, 5, 1, 12, 8, 4, 0);
__m128i shuffle8x8Mask = _mm_setr_epi8(0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15);
void TransposeBlock8x8(uint8_t *src, uint8_t *dst, int srcStride, int dstStride) {
__m128i load0 = _mm_set_epi64x(*(uint64_t*)(src + 1 * srcStride), *(uint64_t*)(src + 0 * srcStride));
__m128i load1 = _mm_set_epi64x(*(uint64_t*)(src + 3 * srcStride), *(uint64_t*)(src + …Run Code Online (Sandbox Code Playgroud) 我有以下问题:
在__m128i寄存器中,按以下顺序排列有16个8位值:
[ 1, 5, 9, 13 ] [ 2, 6, 10, 14] [3, 7, 11, 15] [4, 8, 12, 16]
Run Code Online (Sandbox Code Playgroud)
我想要实现的是有效地改组字节以获得这种排序:
[ 1, 2, 3, 4 ] [ 5, 6, 7, 8] [9, 10, 11, 12] [13, 14, 15, 16]
Run Code Online (Sandbox Code Playgroud)
它实际上类似于4x4矩阵转置,但在一个寄存器内的8位元件上运行.
您能不能指出哪种SSE(优先<= SSE2)指令适合实现这一点?
我想更多地了解_mm_lddqu_si128内部(lddqu自SSE3以来的指令),特别是与_mm_loadu_si128内部(自SSE2以来的movdqu指令)相比.
我_mm_lddqu_si128今天才发现.英特尔内在指南说
当数据穿过缓存行边界时,此内在函数可能比_mm_loadu_si128表现更好
并评论说,它
在某些情况下表现会更好,但从未表现得更差.
那么为什么它没有被更多地使用(SSE3是一个相当低的标准,因为所有的Core2处理器都有它)?为什么数据越过缓存线时性能会更好?是lddqu仅在处理器的某个子集可能更好.比如在Nehalem之前?
我意识到我可以阅读英特尔手册以找到答案,但我认为这个问题对其他人来说可能很有意思.
sse ×3
matrix ×2
optimization ×2
simd ×2
algorithm ×1
c ×1
c++ ×1
intrinsics ×1
transpose ×1
x86 ×1