2010年12月25日 星期六

memset 函式的組語版:setmem。

新的函式出爐囉:

setmem 原始碼。

這次也附上 setzero 的 bug 修正版:

setzero 修正版原始碼。

這次不論是 setzero 修正版或 setmem 都有加上 Altivec ABI,
這通常是編譯器做的事,
但在組語中,程式設計師只有自己手動撰寫,
有 Altivec ABI 的地方,Shady 會用 /* altivec abi */ 做註解。

至於成績,這次 Shady 只放出其 tick 值,如下:

setzero 修正版:16 ~ 17 ticks。
setmem:93 ~ 94 ticks。

這次的測試是用 4KB 的容量為測試對象,
在測試時,主程式是用 C 語言撰寫,其內容大致上如下:

#include < stdlib.h >
#include < stdio.h >
#include < ppu_intrinsics.h >    /* PPU 在 C 語言下的專用底層函式表頭。*/

extern void setzero(void *, int);

int main() {
    unsigned char *d;
    unsigned long long i, j,start, finish;

    if(posix_memalign((void *)&d, 128, 4096)) {    /* 配置一對齊 128 Bytes */
        printf("failed\n");                        /* 邊界的 4KB 記憶體空間。*/
        goto end;
    }
    for(i = 32, j = 0; i > 0; i--, j += 128) {
        __dcbf(d + j);            /* 將所配置的記憶體空間,從 cache 裡消除。*/
    }

    __dcbt(setzero);            /* 將 setzero 函式預先提取到 cache 中 */
    __dcbt(setzero + 128);    /* 這也就是為什麼 setzero 的 tick 值較 */
    __dcbt(setzero + 256);    /* 上次小的原因,而要做 __dcbt(); 多少次,*/
    __dcbt(setzero + 384);    /* 需要視 setzero 之大小,而 __dcbt(); 一次載入 */
    __dcbt(setzero + 512);    /* 之大小為一 cache line,共 128 Bytes。*/
    __dcbt(setzero + 640);    /* Shady 建議最少六次,以掩蓋 cache、memory 的延遲。*/
    __sync();        /* 同步、排空整個 PPU 管線。*/

    start = __mftb();
    setzero((void *) d, 4096);
    finish = __mftb();
    printf("%lld\n", finish - start);    /* tick 值的計算兼印出。*/
end:
    return 0;
}

老實說,這次的 setmem 成績不太理想,
而且還有當配置的記憶體超過 4KB 時,
一次所要設置的記憶體量不要超過 2KB,
否則將看到 2000 ticks 以上的成績出現,
這種狀況,不論是 Shady 的函式或別人的函式,
甚至是 Linux 的 libc 都會大失速。
當然 Shady 會找出原因所在,
而 setmem 的效率,Shady 也會盡量改進,
之後 Shady 還是會不定時釋放出新函式或修正函式,
只不過,可能頻率不會太常,
請大家見諒。

沒有留言:

張貼留言