工具/软件:
我将比较几种向 CLA 协处理器和 C28x 主处理器传递数据的不同方法。 我希望数据传输是可扩展的、因此使用类似 memcpy 的例程来执行复制、但是、我遇到了 CLA 的预期问题、并且缺少 RPTB 指令。 我要了解的方法有:
void element_by_element_copy(struct_t * in, struct* out){
out->field_1 = in->field_2;
...
...
out->field_n = in->field_n;
}
void memcpy(struct_t * in, struct* out){
uint32_t *src = in;
uint32_t *dst = in;
for (uint16_t i = 0; i < (sizeof(struct_t) / 2); i++){
dst[i] = src[i];
}
}
void unroll_memcpy(struct_t * in, struct* out){
uint32_t *src = in;
uint32_t *dst = in;
#pragma UNROLL(sizeof(struct_t) / 2)
for (uint16_t i = 0; i < (sizeof(struct_t) / 2); i++){
dst[i] = src[i];
}
}
正如预期的那样、逐元素复制的性能最高、但我注意到使用 UNROLL pragma 与 for 循环会得到几乎相同的代码。 唯一的区别似乎是在展开循环时、CLA 编译器会复制分支所需的不必要的 MNOP 指令。 请参阅下面的汇编输出示例:
/* Assembly generation - Element by Element Copy */
; MAR0 assigned to dst_buff;
; Copy first element
MMOV32 MR0,@src_buff ; [CPU_FPU]
MMOV32 *MAR0,MR0 ; [CPU_FPU]
; Copy second element
MMOV32 MR0,@src_buff+2 ; [CPU_FPU]
MMOV32 *MAR0+[#2],MR0 ; [CPU_FPU]
...
...
; Copy nth element
MMOV32 MR0,@src_buff+n ; [CPU_FPU]
MMOV32 *MAR0+[#n],MR0 ; [CPU_FPU]
/* Assembly generation - Unrolled For Loop */
; MAR0 assigned to dst_buff;
; Copy 1st 32 bits
MMOV32 MR0,@src_buff ; [CPU_FPU]
MMOV32 *MAR0,MR0 ; [CPU_FPU]
MNOP ; [CPU_FPU]
MNOP ; [CPU_FPU]
MNOP ; [CPU_FPU]
; Second 32 bits
MMOV32 MR0,@src_buff+2 ; [CPU_FPU]
MMOV32 *MAR0+[#2],MR0 ; [CPU_FPU]
MNOP ; [CPU_FPU]
MNOP ; [CPU_FPU]
MNOP ; [CPU_FPU]
...
...
; Copy nth 32 bits
MMOV32 MR0,@src_buff+n ; [CPU_FPU]
MMOV32 *MAR0+[#n],MR0 ; [CPU_FPU]
那么、我的问题是、是否可以在展开循环时强制 CLA 编译器删除这些 NOP 指令? 我假设在循环仅部分展开的情况下会注入 NOP、但在我们的用例中、最好完全展开循环、因为这需要针对速度而不是代码大小进行优化。