许 菁,黄 震,韩向清,付 林
(中国船舶集团有限公司第八研究院,南京 211153)
在雷达信号处理或数据处理中,当使用PPC的RapidIO进行数据传输时,通常采用门铃来实现数据传输完成后的消息中断。对于这样的门铃中断函数,需要尽可能快地完成数据转移,以避免多次传输导致来不及处理的数据丢失。一般在进行大量不确定数量数据传输时,会在数据头中设计一个字段来描述当次传输的数量。现有处理方法会通过内存复制函数(memcpy)将数据头复制一个副本,然后对副本中的长度字段进行读取。
本文对现有处理方法进行优化,以减少使用内存复制函数(memcpy)的应用,提高输出读取的效率。
在PowerPC的RapidIO数据传输时,需要进行内存地址映射,读取传输的数据是通过直接访问内存地址实现的。
编译器实现直接(或间接)地址访问读取数据,可以表达为
MOV AX,[Address]
(1)
而对结构体的字段访问表达为
MOV AX,[Address + offset]
(2)
式中,Address为结构体的首地址;offset为字段相对首地址的偏移量。
采用内存复制函数(memcpy)复制数据头的副本,实际上是对式(1)、跳转语句(jnz)以及计数器的多次调用,它主体的汇编表达将如下所示:
10:MOV CX,Count
20:MOVEAX,[Address]
30:MOV [DST],EAX
40:INC Address
(3)
50:INC DST
60:DEC CX
70:JNZ 20
同时,采用内存复制函数(memcpy)还将带来函数开销,如寄存器保存、函数堆栈等操作,这将涉及ESP、EBP等栈寄存器和EAX、ECX、EDX等调用者寄存器及EBX、ESI、EDI等被调用者寄存器的操作和保存。
首先,调用内存复制函数(memcpy)时,需要先将EAX、ECX、EDX等调用者寄存器进行保存:
10:PUSH EAX
20:PUSH EBX
30:PUSH ECX
其次,需要将输入给内存复制函数(memcpy)的参数,入栈后推送给内存复制函数(memcpy):
10:MOV EAX,[Address1]
20:PUSH EAX
30:MOV EAX,[Address2]
40:PUSH EAX
然后,内存复制函数(memcpy)执行式(3)所示的函数主体;……