接前一文章之內容 write V.S. fwrite
分析 write() & fwrite() 效能。
此 gLibc 的環境中,筆者的 BUFSIZ 值為 8192,即 fwrite 內含 8192 bytes buffer。(見之前之文章)。
以嵌入式系統為環境,SATA write 來測試其表現, 在小 size 測試中(512、1024bytes…),fwrite 較為穩定,但由於 fwrite 會多一次 COPY,所以當"單次寫入"值愈大,效能會被 write() 所趕上 (此例中在 4096bytes 時 fwrite 被 write 趕上效能)。
 
   
CPU 使用效率,應該是受到 COPY 的影響, fwrite 消耗全部 CPU 的量。
 
   
 
結論:
程式設計師在實作 File Write 時,如使用 fwrite 要小心 CPU 飆高的狀況,用 fwrite 的優點是不用 care 單次寫入的量,因為 glibc 幫你管理好了,且效能很穩定。
使用 write 時,需要較高段的程式技巧,選擇一個單次寫入量的值,變得十分重要,關係到你的 Performance 會是 7MB/s (2048 為單位),還是 37MB/s (4096 為單位),兩者差距很大。
 
測試Code參考如下:
 
//測試 fwrite
 
void test_fwrite(void)
{
    FILE *stream;
    char *buf;
    int total_size=0,ret;
    unsigned int perf;
    unsigned long long start_time,last_time;
 
    stream = fopen(FILENAME, "wb");
    if (!stream) {
        perror("fopen");
        return;
    }
    buf = malloc(bufsize);
    if (!buf) {
        perror("malloc");
        return;
    }
    start_time = av_gettime();
    while (total_size < TEST_SIZE) {
        ret = fwrite(buf, bufsize, 1, stream);
        if (!ret) {
            perror("fwrite");
            return;
        }
        total_size += bufsize;
        if ((total_size & 0x3fffff) == 0) {
            printf("\r0x%x Bytes",total_size);fflush(stdout);
        }
    }
    fclose(stream);
    last_time = av_gettime();
 
    perf = total_size / (unsigned int)((last_time-start_time)/1000); //ms
    perf = perf * 1000; //sec
    perf = perf / 1048576;
    printf("\nfwrite Performance %dMBytes/s\n",perf);
}
 
//測試 write
void test_write(void)
{
    int fd;
    char *buf;
    int total_size=0,ret;
    unsigned int perf;
    unsigned long long start_time,last_time;
   
    fd = open(FILENAME, O_CREAT|O_RDWR);
    if (fd < 0) {
        perror("open");
        return;
    }
 
    buf = malloc(bufsize);
    if (!buf) {
        perror("malloc");
        return;
    }
    start_time = av_gettime();
    while (total_size < TEST_SIZE) {
        ret = write(fd, buf, bufsize);
        if (!ret) {
            perror("write");
            return;
        }
        total_size += bufsize;
        if ((total_size & 0x3fffff) == 0) {
            printf("\r0x%x Bytes",total_size);fflush(stdout);
        }
    }
    close(fd);
    last_time = av_gettime();
 
    perf = total_size / (unsigned int)((last_time-start_time)/1000); //ms
    perf = perf * 1000; //sec
    perf = perf / 1048576;
    printf("\nwrite Performance %dMBytes/s\n",perf);
}
文章標籤
全站熱搜
創作者介紹
創作者 小寫 的頭像
小寫

小寫的部落格

小寫 發表在 痞客邦 留言(0) 人氣(1,392)