一般情况下你的电脑cpu都不会跑满,比如我的电脑有8个逻辑处理器。
就相当于8个人,而我们写的辣鸡程序一般都是一个线程。所以大部分下情况下电脑的程序都是 一核有难,多核围观。
今天我来教大家两行代码实现并行运算,让你的程序速度提高8倍。
起因
好友的辣鸡代码跑的贼慢,他的脑袋上有很多小问号,为什么同样的算法,matlab都比c++跑的快好多倍。
经过研究发现辣鸡代码在运行的时候cpu只有20%的利用率,其他核都在偷懒!!!我们要把cpu所有核心都利用起来。
方法
这个时候就要拿出并行运算利器了,大家可能以为并行很复杂。实际上,只要我们使用openmp只需要两行代码就能实现并行。
第一步:
头文件
#include
第二步:
一般情况下只有for循环需要并行,在for循环前加
int main(){#pragma omp parallel for for (char i = 'a'; i <= 'z'; i++) std::cout << i << std::endl; return 0;}
只需要在for之前加上一句pragma就可以实现并行化了
OpenMP 对可以多线程化的循环有如下五个要求:
- 循环的变量变量(就是i)必须是有符号整形,其他的都不行。
- 循环的比较条件必须是< <= > >=中的一种
- 循环的增量部分必须是增减一个不变的值(即每次循环是不变的)。
- 如果比较符号是< <=,那每次循环i应该增加,反之应该减小
- 循环必须是没有奇奇怪怪的东西,不能从内部循环跳到外部循环,goto和break只能在循环内部跳转,异常必须在循环内部被捕获。
其中的坑:
两行代码之后,辣鸡代码开始疯狂报错,这是由于很多被赋值的变量都定义都在循环之外的。
通俗来讲
并行相当于一个人的工作几个人合作一起做,每个人做的事情不能互相影响,大家同时往一个变量放东西或者拿东西,这样几个人的动作就打架了,不仅不能提高效率,而且得到错误的结果。
专业来讲
编译器会把这个循环多线程化,但是并不能实现我们想要的加速效果,得出的数组含有错误的结构。因为每次迭代都依赖于另一个不同的迭代,这被称之为竞态条件。要解决这个问题只能够重写循环或者选择不同的算法。竞态条件很难被检测到,因为也有可能恰好程序是按你想要的顺序执行的(就是说跑出来的数据有时候对有时候错,随机出错)。
那句古话说的好,你爱你的老板,给他写并行吧,恨你的老板,给他写并行吧!
最后
好友的辣鸡代码终于不辣鸡了,运行效率提升了8倍,科研效率飞速提升,我也白嫖了一顿晚饭,皆大欢喜。这个故事告诉我们,写代码要用并行!!!