作为一名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
}
当然,一般批评也受到赞赏。 :)
答案 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?
为每个平均测量值获得多少个周期