【发布时间】:2014-01-08 20:40:51
【问题描述】:
我需要优化我在 c 中的混合代码以获得更快的响应时间,因此我决定使用内联汇编将两个缓冲区混合到一个新的更大的缓冲区中。基本上我将左右声道分开,我想将它们放在一起放入缓冲区。所以我需要从左通道放 2 个字节,然后从右通道放两个字节,依此类推。 为此,我决定将我的 3 个指针发送到我的汇编代码,在那里我打算将左通道指针指向的内存复制到 R0 寄存器中,并将右通道指针指向的内存复制到 R1 之后我打算将 R0 和 R1 混合到 R3 和 R4 中稍后将这些寄存器保存到内存中。(我打算使用其他空闲寄存器来执行相同的过程并通过流水线减少处理时间)
所以我有两个带有数据的寄存器 R0 和 R1,需要将它们混合到 R3 和 R4 中,我需要最终得到 R3 = R0HI(high-part) + R1HI(high-part) 和 R4 = R0LO (低频) + R1LO(低频)
我可以考虑使用按位移位,但我的问题是,是否有一种更简单的方法来做到这一点,例如 intel x86 架构,您可以将数据传输到 ax 寄存器,然后将我们 ah 作为高部分和 al 作为低部分部分?
我的想法对吗?有更快的方法吗?
我在 ndk 中的实际(不工作)代码
void mux(short *pLeftBuf, short *pRightBuf, short *pOutBuf, int vecsamps_stereo) {
int iterations = vecsamps_stereo / 4;
asm volatile(
"ldr r0, %[outbuf];"
"ldr r1, %[leftbuf];"
"ldr r2, %[rightbuf];"
"ldr r3, %[iter];"
"ldr r4, [r3];"
"mov r8, r4;"
"mov r9, r0;"
"mov r4, #0;"
"mov r10, r4;"
"loop:; "
"ldr r2, [r1];"
"ldr r3, [r2];"
"ldr r7, =0xffff;"
"mov r4, r2;"
"and r4, r4, r7;"
"mov r5, r3;"
"and r5, r5, r7;"
"lsl r5, r5, #16;"
"orr r4, r4, r5;"
"lsl r7, r7, #16;"
"mov r5, r2;"
"and r5, r5, r7;"
"mov r6, r3;"
"and r6, r6, r7;"
"lsr r6, r6, #16;"
"orr r5, r5, r6;"
"mov r6, r9;"
"str r4, [r6];"
"add r6, r6, #1;"
"str r5, [r6];"
"add r6, r6, #1;"
"mov r9, r6;"
"mov r4, r10;"
"add r4, r4, #1;"
"mov r10, r4;"
"cmp r4, r8;"
"blt loop"
:[outbuf] "=m" (pOutBuf)
:[leftbuf] "m" (pLeftBuf) ,[rightbuf] "m" (pRightBuf),[iter] "m" (pIter)
:"r0","r1","r2","r3","memory"
);
}
【问题讨论】:
-
在考虑汇编程序之前,您应该检查现有 C 实现的性能 - 很可能通过对其进行分析。在此处发布您的代码会有所帮助 - 就像准确了解您正在使用的 ARM 设备一样吗?有霓虹灯吗?
-
您能否澄清一下您是指成对的 16 + 16 到 32 位加法还是只是交错?我提到的打包添加指令可能不相关,但其余的都是任何一种方式。
-
@marko 我在单独的通道中进行信号处理,使用 fft eq,在此之前进行压缩和其他一些事情,时间还不错,但我在这部分发现了一个瓶颈。跨度>
-
@Notlike,我的意思是成对的 16 + 16 位加法,我的目标是带和不带霓虹灯的 arm 处理器,下一个优化将利用它的优势为霓虹灯设备编译。
标签: c audio assembly arm inline-assembly