c – 为什么size_t和unsigned int比int慢?
我正在使用下面的简单交换排序算法在
Windows中的Visual Studio项目中尝试不同的整数类型.处理器是英特尔.代码是在Release x64中编译的.优化设置为“最大化速度(/ O2)”.与编译设置对应的命令行是
/permissive- /GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"x64Releasevc141.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /Fa"x64Release" /EHsc /nologo /Fo"x64Release" /Fp"x64ReleaseSpeedTestForIntegerTypes.pch" /diagnostics:classic 代码本身: #include <ctime> #include <vector> #include <iostream> void sort(int N,int A[],int WorkArray[]) // exchange sort { int i,j,index,val_min; for (j = 0; j < N; j++) { val_min = 500000; for (i = j; i < N; i++) { if (A[i] < val_min) { val_min = A[i]; index = i; } } WorkArray[j] = A[j]; A[j] = val_min; A[index] = WorkArray[j]; } } int main() { std::vector<int> A(400000),WorkArray(400000); for(size_t k = 0; k < 400000; k++) A[k] = 400000 - (k+1); clock_t begin = clock(); sort(400000,&A[0],&WorkArray[0]); clock_t end = clock(); double sortTime = double(end - begin) / CLOCKS_PER_SEC; std::cout << "Sort time: " << sortTime << std::endl; return 0; } WorkArray只需要在排序之前保存向量. #include <ctime> #include <vector> #include <iostream> void sort(int N,size_t A[],size_t WorkArray[]) // exchange sort { int i,index; size_t val_min; for (j = 0; j < N; j++) { val_min = 500000U; for (i = j; i < N; i++) { if (A[i] < val_min) { val_min = A[i]; index = i; } } WorkArray[j] = A[j]; A[j] = val_min; A[index] = WorkArray[j]; } } int main() { std::vector<size_t> A(400000),&WorkArray[0]); clock_t end = clock(); double sortTime = double(end - begin) / CLOCKS_PER_SEC; std::cout << "Sort time: " << sortTime << std::endl; return 0; } 请注意,我仍然为函数局部变量i,N保留类型int,因此在两种情况下,只有两个算术运算i和j应该花费相同的时间.因此,这种放缓与其他原因有关.它与内存对齐问题或寄存器大小或其他内容有关吗? 但最令人发指的部分是当我将int更改为unsigned int时. unsigned int和int都占用相同的字节数,即4(sizeof显示).但是unsigned int的运行时间是65.8秒!虽然第一个结果有点可以接受,但第二个结果让我很困惑!为什么运行这样一个甚至不涉及符号检查的简单算法所需的时间差别如此之大? 感谢所有人都解决了这两个问题.我在哪里可以开始阅读有关这些硬件级优化特性的更多信息?我不关心排序算法本身,它仅用于说明问题. 更新:再一次,我强调在所有三种情况下我都使用int作为数组索引. 解决方法
检查所有3个变量(int,unsigned,size_t)的生成程序集,最大的区别是在int情况下,sort函数中的循环被展开并使用SSE指令(一次处理8个int),而在其他两个案例都没有.有趣的是,在int情况下调用sort函数,而在另外两个函数中将其内联到main中(可能是由于循环展开导致函数的大小增加).
我正在使用cl / nologo / W4 / MD / EHsc / Zi / Ox从命令行编译,使用dumpbin来获取反汇编,使用工具集Microsoft(R)C/C++优化编译器版本19.12.25830.2 for x64. 对于int,我的执行时间约为30秒,而其他两个执行时间为100秒. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |