| byte0 | byte1 | byte2 | etc..
| A11 A10 A9 A8 A7 A6 A5 A4 | B11 B10 B9 B8 B7 B6 B5 B4 | B3 B2 B1 B0 A3 A2 A1 A0 | etc..
我稍微重新排列成以下模式:
| byte0 | byte1 | byte2 | etc..
| A11 A10 A9 A8 A7 A6 A5 A4 | A3 A2 A1 A0 B11 B10 B9 B8 | B7 B6 B5 B4 B3 B2 B1 B0 | etc..
我已经用以下代码在一个每3字节循环中使其工作。
void CSI2toBE12(uint8_t* pCSI2, uint8_t* pBE, uint8_t* pCSI2LineEnd)
{
while (pCSI2 < pCSI2LineEnd) {
pBE[0] = pCSI2[0];
pBE[1] = ((pCSI2[2] & 0xf) << 4) | (pCSI2[1] >> 4);
pBE[2] = ((pCSI2[1] & 0xf) << 4) | (pCSI2[2] >> 4);
// Go to next 12-bit pixel pair (3 bytes)
pCSI2 += 3;
pBE += 3;
}
}
但是以字节粒度进行操作对性能来说并不理想。目标 CPU 是 64 位 ARM Cortex-A72(树莓派计算模块 4)。为了背景,这段代码将 MIPI CSI-2 位打包的原始图像数据转换为 Adobe DNG 的位打包形式。
我希望能够通过使用 SIMD 指令集获得显著的性能改进,但我不太确定从何处开始。我已经有了用于翻译指令集的 SIMDe 头文件,因此欢迎使用 AVX/AVX2 解决方案。
ld3
指令,可以加载48个字节并将它们解压到三个寄存器中。因此,您将在一个寄存器中拥有所有的byte0
,以此类推。我认为相应的内部函数是vld3q_u8
,返回uint8x16x3_t
。然后,您可以像当前代码一样进行移位和掩码操作,并使用st3
(vst3q_u8
)重新压缩和存储。 - Nate Eldredgeld3/st3
的等效指令,所以SIMDe可能无法发挥作用。 - Nate Eldredge