C中的快速交错操作?

Mik*_*ima 5 c arrays performance memcpy

我需要将两个数组以四个为一组组合成第三个。具体来说,对于输入数组

    A0, A1, A2, A3, A4, A5, A6, A7 ...
    B0, B1, B2, B3, B4, B5, B6, B7 ...
Run Code Online (Sandbox Code Playgroud)

输出应该是

    A0 A1 A2 A3   B0 B1 B2 B3   A4 A5 A6 A7   B4 B5 B6 B7, ...,
Run Code Online (Sandbox Code Playgroud)

从某种意义上说,这与Fastest de-interleave operation in C? 中提出的 de-interleave 问题相反

为了更有趣,两个缓冲区包含分别为 8 位和 16 位宽的元素。我已经编写了一些代码来执行此操作,但分析表明它花费了大量时间,因此我正在寻找加快速度的方法。由于我的目标 CPU (LEON) 不提供它们,因此不能选择 SIMD 内在函数。我的 CPU 的字长为 16 位。

我尝试了不同的循环方式,这是我迄今为止最快的版本:

#include <stdint.h>

#define BUFSZ 1024

register int i;
int8_t  A[BUFSZ]; // 1st buffer
int16_t B[BUFSZ]; // 2nd buffer
int16_t interleaved[2*BUFSZ]; // the two buffers combined

int8_t  *pA;
int16_t *pB, *pinterleaved;

        pinterleaved=interleaved;
        for(i=BUFSZ/4, pA=A, pB=B; i-->0; pinterleaved+=8, pA+=4, pB+=4){
                pinterleaved[0]=pA[0]; pinterleaved[1]=pA[1]; pinterleaved[2]=pA[2]; pinterleaved[3]=pA[3];
                pinterleaved[4]=pB[0]; pinterleaved[5]=pB[1]; pinterleaved[6]=pB[2]; pinterleaved[7]=pB[3];
        }       
Run Code Online (Sandbox Code Playgroud)

有更快实施的想法吗?

438*_*427 3

优化性能通常是一项非常特定于系统的任务。所以我的观察可能在您的系统上无效。

无论如何,FWIW,在我的系统上,通过将最后 4 个分配(使用 的分配pB)替换为memcpy.

我替换:

pinterleaved[4]=pB[0]; pinterleaved[5]=pB[1]; pinterleaved[6]=pB[2]; pinterleaved[7]=pB[3];
Run Code Online (Sandbox Code Playgroud)

memcpy(pinterleaved + 4, pB, 4 * sizeof *pB);
Run Code Online (Sandbox Code Playgroud)

并获得了 > 25% 的性能提升。