February 27, 2006

善用 GCC builtins 實現 Vectorization

之前的 blog [Vectorization 的呈現] 提到 GCC 4 vectorization optimization 的使用,而 GCC 3.3/3.4 可透過 GCC builtins 和 MMX intrinsics,前者的使用可用以下這個小程式來體驗:
#include <stdio.h>
typedef int v4hi __attribute__ ((mode(V4HI)));
typedef int v2si __attribute__ ((mode(V2SI)));

int main(int argc, char *argv[])
{
        short pa[4] = { 0x8000, 0x8000, 1, -1 };
        short pb[4] = { 0x8000, 0x7FFF, -1, -2 };

        v4hi va, vb;
        v4hi vsum;

        va = ((v4hi *) pa)[0];
        vb = ((v4hi *) pb)[0];

        vsum = va + vb;

        printf("Use MMX Intrinsics to compute vec_add: %llx \n", 
                  (long long)vsum);

        return 0;
}

在 Intel PXA27x 的組譯碼為: (部份)
    .LC2:
            .ascii  "Use MMX Intrinsics to compute vec_add: %llx \n\000"
            .text
            .align  2
            .global main
            .type   main, %function
    main:
            @ args = 0, pretend = 0, frame = 16
            @ frame_needed = 0, uses_anonymous_args = 0
            stmfd   sp!, {r4, lr}
            mov     r4, #8
            sub     sp, sp, #16
            mov     r2, r4
            ldr     r1, .L2
            add     r0, sp, r4
            bl      memcpy
            mov     r2, r4
            ldr     r1, .L2+4
            mov     r0, sp
            bl      memcpy
            wldrd   wr2, [sp, #8]
            wldrd   wr0, [sp, #0]
            ldr     r0, .L2+8
            waddh   wr1, wr2, wr0
            tmrrc   r2,r3,wr1
            bl      printf
            mov     r0, #0
            add     sp, sp, #16
            ldmfd   sp!, {r4, pc}
    .L3:
            .align  2
    .L2:
            .word   .LC0
            .word   .LC1
    
可以發現 GCC 將向量加法轉換為 Wireless MMX 指令集,以兩道加法完成 32 * 4 bit 整數運算。另外,MMX intrinsics 的使用可參考 [我寫的小程式],可以編譯為 x86 (MMX) 與 arm (PXA27x) 的機械碼,透過 gdb sim 可以看到微妙的差異。
由 jserv 發表於 February 27, 2006 09:05 PM
迴響