const float* H; //input data from elsewhere
const float32x4x4_t hCols = vld4q_f32(H);
const float32x4_t hCol0 = vld1q_f32(H + 0);
const float32x4_t hCol1 = vld1q_f32(H + 4);
const float32x4_t hCol2 = vld1q_f32(H + 8);
const float32x4_t hCol3 = vld1q_f32(H + 12);
我使用hCol0、hCol1、hCol2、hCol3的代码被hCols.val、hCols.val1、hCols.val2、hCols.val3替换,但现在我得到了非常奇怪的输出。
对于vld4q_f32来说,这两个负载不完全相同吗?
发布于 2017-12-01 10:55:40
从一开始,vld4
是一个与vld1
非常不同的指令。
虽然vld1
是一个简单的负载,但vld4
是一个扩展负载,其中每个值都分布在四个寄存器之间,一个接一个的元素,一个接一个的寄存器。
vld4q_f32(pSrc) will translate to:
vld4.32 {d0, d2, d4, d6}, [pSrc]!
vld4.32 {d1, d3, d5, d7}, [pSrc]
*pSrc:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E
================================================
And the values are loaded as following:
q0 (d0 + d1): 0, 4, 8, C
q1 (d2 + d3): 1, 5, 9, D
q2 (d4 + d5): 2, 6, A, E
q3 (d6 + d7): 3, 7, B, F
在程序集中,可以用一个指令直接加载多个寄存器,如:
vld1.32 {q0, q1}, [pSrc]!
vld1.32 {q2, q3}, [pSrc]
And the values are loaded as following:
q0 (d0 + d1): 0, 1, 2, 3
q1 (d2 + d3): 4, 5, 6, 7
q2 (d4 + d5): 8, 9, A, B
q3 (d6 + d7): C, D, E, F
然而,在本质上,您必须通过寄存器注册它: float32x4x4_t hCols;
hCols.val[0] = vld1q_f32(H + 0);
hCols.val[1] = vld1q_f32(H + 4);
hCols.val[2] = vld1q_f32(H + 8);
hCols.val[3] = vld1q_f32(H + 12);
在Android 3.01上,vld1q_f32_x4
是为此目的而定义的,但它似乎仍然存在缺陷。至少我还没能成功地建造。
顺便说一句,你想做4x4矩阵乘法吗?恭喜,你刚刚发现了如何在vld4
中自动转置矩阵;
不过,不要把你的时间浪费在本质上。程序集版本的运行速度几乎是的三倍,而我完成了由Clang编译的1:1的内嵌翻译,这是由Android 3.01附带的。这真的很烦人。
使用本质是纯粹的浪费时间,当然,至少在手臂上是这样。
https://stackoverflow.com/questions/47588370
复制相似问题