赞
踩
对于C++开发者来说,写一个累加算法是可以说是小菜一碟,但是对于累加算法的性能却各有不同,一个简单的累加算法如下:
- int res = 0;
- int num = 5000000;
- start = std::chrono::system_clock::now();
- for (int i = 1; i <= num; i++)
- {
- res += i;
- }
- end = std::chrono::system_clock::now();
- std::chrono::duration<double> dura = end - start;
- std::cout << "共耗时:" << dura.count() << "s" << std::endl;
对于此程序,我们可以测试其性能,测试结果如下:
为了优化上述程序,我们可以将循环进行部分展开,以减少循环次数,代码如下:
- int res = 0;
- int num = 5000000;
- start = std::chrono::system_clock::now();
- for (int i = 1; i <= num; i+=4)
- {
- res += i;
- res += i + 1;
- res += i + 2;
- res += i + 3;
- }
- end = std::chrono::system_clock::now();
- std::chrono::duration<double> dura = end - start;
- std::cout << "共耗时:" << dura.count() << "s" << std::endl;
此时,我们将循环次数缩小四倍,每次循环时,将四个值累加到res中,性能如下:
可以看到性能提升了0.00463s。
- int res = 0;
- int num = 5000000;
- int r0 = 0, r1 = 0, r2 = 0, r3 = 0;
- start = std::chrono::system_clock::now();
- for (int i = 1; i <= num; i+=4)
- {
- r0 += i;
- r1 += i + 1;
- r2 += i + 2;
- r3 += i + 3;
- }
- res = r0 + r1 + r2 + r3;
- end = std::chrono::system_clock::now();
- std::chrono::duration<double> dura = end - start;
- std::cout << "共耗时:" << dura.count() << "s" << std::endl;
此时我们使用不同的变量进行累加,最终再将累加的结果求和,此时性能如下:
此时的性能又有了进一步提升,进一步提升了0.00418s。
这个关键字请求编译器尽可能的将变量存在CPU内部寄存器
中,而不是通过内存寻址访问,以提高效率。代码如下:
- int res = 0;
- int num = 5000000;
- register int r4 = 0, r5 = 0, r6 = 0, r7 = 0;
- start = std::chrono::system_clock::now();
- for (int i = 1; i <= num; i += 4)
- {
- r4 += i;
- r5 += i + 1;
- r6 += i + 2;
- r7 += i + 3;
- }
- res1 = r4 + r5 + r6 + r7;
- end = std::chrono::system_clock::now();
- std::chrono::duration<double> dura = end - start;
- std::cout << "共耗时:" << dura.count() << "s" << std::endl;
此时性能如下:
此时性能提升了0.00418s.
注意是"尽可能",不是绝对
。你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很多很多register 变量,它累死也可能不能全部把这些变量放入寄存器吧。
gcc提供了大量优化选项,用来对编译时间,目标文件长度,执行效率三个维度进行不同的取舍和平衡。
我们在上个优化的基础上,给cmake添加O3优化,如下:
- set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -O3 -Wall")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wall")
测试结果如下:
此时性能提升了0.00322s, 可以看到编译器本身对程序优化效果还是很大的。
O3优化本身就有优化展开的优化,和我们的循环展开有冲突吗?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。