未对齐数据的性能损失

时间:2014-10-28 13:31:40

标签: c performance alignment

作为一名CS学生,我试图了解计算机的基础知识。当我偶然发现this website时,我想自己测试那些性能惩罚。我明白他在谈论什么以及为什么会发生/应该发生。

无论如何,这里是我用来称呼他写的那些函数的代码:

int main(void)
{
    int i = 0;
    uint8_t alignment = 0;
    uint8_t size = 1024 * 1024 * 10; // 10MiB
    uint8_t* block = malloc(size);

    for(alignment = 0; alignment <= 17; alignment++)
    {
        start_t = clock();
        for(i = 0; i < 100000; i++)
            Munge8(block + alignment, size);

        end_t = clock();
        printf("%i\n", end_t - start_t);
    }
    // Repeat, but next time with Munge16, Munge32, Munge64
}

我不知道我的CPU和RAM非常快,但所有4种功能(Munge8,Munge16,Munge32和Munge64)的输出总是3或4(随机,无模式)。

这可能吗?重复100000应该是更多的工作要做,还是我错了?我正在使用Windows 7企业版x64,英特尔酷睿i7-4600U CPU @ 2.10GHz。关闭所有编译器优化,即/ Od。

关于SO的所有相关问题都没有解答为什么我的解决方案无效。

我做错了什么?非常感谢任何帮助。

修改 首先:非常感谢你的帮助。在将大小类型从uint8_t更改为uint32_t后,我将所有内部循环更改为导致测试函数的未定义行为分为两行:

while( data32 != data32End ) 
{
    data32++;
    *data32 = -(*data32);
}

现在我获得了相对稳定的25 / 26,12 / 13,6和3滴答输出,计算了100次重复的平均值。这是合乎逻辑的结果吗?这是否意味着我的架构处理未对齐访问与对齐访问一样快(或慢)?我是否测量不准确的时间?或者除以10时是否存在精度问题?我的新代码:

int main(void)
{
    int i = 0;
    uint8_t alignment = 0;
    uint64_t size = 1024 * 1024 * 10; // 10MiB
    uint8_t* block = malloc(size);


    printf("%i\n\n", CLOCKS_PER_SEC); // yields 1000, just for comparison how fast my machine 'ticks'
    for(alignment = 0; alignment <= 17; alignment++)
    {
        start_t = clock();
        for(i = 0; i < 100; i++)
            singleByte(block + alignment, size);

        end_t = clock();
        printf("%i\n", (end_t - start_t)/100);
    }
    // Again, repeat with all different functions
}

当然,一般批评也受到赞赏。 :)

2 个答案:

答案 0 :(得分:0)

由于整数溢出而失败:

uint8_t size = 1024 * 1024 * 10; // 10MiB

它应该是:

const size_t size = 1024 * 1024 * 10; // 10MiB

不知道为什么你会使用8位数量来保存那么大的东西。

调查如何为编译器启用所有警告。

答案 1 :(得分:0)

您的时钟功能似乎有问题。 CLOCKS_PER_SEC 1000 对于您的处理器来说太低了,即使激活CPU限制(如果关闭频率缩放,您应该得到2100000左右)。使用cycle.h

为每个平均测量值获得多少个周期