如何针对C中各种大小的缓冲区测试WKdm算法

时间:2013-11-24 23:35:28

标签: c algorithm

我正在尝试测试WKdm算法,看看它对100KB,1MB和10MB的缓冲区的性能如何;但是,在我的测试程序中,任何大于1KB的缓冲区都会抛出EXC_BAD_ACCESS:无法访问内存。

我使用了WKdm.c的main(),这是一个简单的测试,并尝试转换它,以便我可以更改要压缩的输入缓冲区的大小。

我正在使用WKDM算法的标准Scott Kaplan实现,该算法由源文件和头文件组成,找到here。我试过Linux和OS X 32位。

#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <strings.h>
#include <sys/time.h>
#include "WKdm.h"

#define PAGE_SIZE_IN_WORDS 1024
#define PAGE_SIZE_IN_BYTES 4096

int main() {

    WK_word i;
    //int testSize = 1024; //1KB Works
    int testSize = 102400; //100KB causes EXC_BAD_ACCESS

    int testNumWords = testSize / sizeof(WK_word);
    printf("testSize = %d bytes or %d words\n", testSize, testNumWords);

    WK_word* source_buf = (WK_word*) malloc(testSize * 2);
    WK_word* dest_buf = (WK_word*) malloc(testSize * 2);
    WK_word* udest_buf = (WK_word*) malloc(testSize * 2);

    for (i = 0; i < testNumWords; i++) {
        source_buf[i] = rand() % 1000; //Semi-random: 0-999 stored in each 4-byte word
    }

    source_buf[testNumWords + 1] = 99999;
    udest_buf[testNumWords + 1] = 55555;

    printf("first 50 words of source_buf are:\n");
    for (i = 0; i < 50; i++)
        printf(" %d", source_buf[i]);
    fflush(stdout);

    struct timeval t0;  struct timeval t1;
    gettimeofday(&t0, 0);

    // Compress the source_buf into the dest_buf
    i = WKdm_compress(source_buf, dest_buf, testNumWords);

    gettimeofday(&t1, 0);
    long elapsed = (t1.tv_sec - t0.tv_sec) * 1000000 + t1.tv_usec - t0.tv_usec;

    printf("\nWKdm_compress size in bytes: %u\n", i);
    printf("Time to compress: %lu microseconds\n\n", elapsed);

    printf("redzone value at end of source buf (should be 99999) is %u\n",
            source_buf[testNumWords + 1]); fflush(stdout);

    gettimeofday(&t0, 0);

    WKdm_decompress(dest_buf, udest_buf, testNumWords);

    gettimeofday(&t1, 0);
    elapsed = (t1.tv_sec - t0.tv_sec) * 1000000 + t1.tv_usec - t0.tv_usec;
    printf("Time to decompress: %lu microseconds\n\n", elapsed);

    printf("redzone value at end of udest buf (should be 55555) is %u\n", udest_buf[testSize + 1]);

    printf("first 50 words of udest_buf are:\n");
    for (i = 0; i < 50; i++)
        printf(" %d", udest_buf[i]);

    i = bcmp(source_buf, udest_buf, 100);

    printf("\nbcmp of orig. and compr'd/decompr'd copy (should be 0) is %u\n", i);
    fflush(stdout);
    return 0;
}

1 个答案:

答案 0 :(得分:2)

Scott Kaplan实现的WKdm算法是针对4KB的页面大小而设计的。如果要压缩大于4KB的任何内容,则需要在建模期间增加用于以中间形式保存输出数据的数组的大小。这三个数组位于WKdm_compress和WKdm_decompress函数的顶部。您可以增加它们的大小来存储更多的中间数据,但是看起来comp / decomp时间会急剧增加。

此外,压缩大于1MB的缓冲区会导致更多超出范围的异常。因此,除非您想要进行大量的重写,否则您可能只想将WKdm用于小于4KB的缓冲区。

作为旁注,Kaplan的WKdm实现针对压缩4KB进行了优化这一事实可能是Apple在OS X 10.9 Mavericks中使用它进行内存压缩的一个重要原因,它的页面大小为4KB。