use*_*803 3 c++ optimization gcc g++ core
我有一个带有多个For循环的c ++程序; 每个运行大约500万次迭代.是否有任何命令我可以使用g ++来生成.exe将使用多个核心; 即在第一个核心上运行第一个For循环,同时在第二个核心运行第二个For循环?我已经尝试了-O3和-O3 -ftree-vectorize,但在这两种情况下,我的cpu使用率仍然仅在25%左右徘徊.
编辑:这是我的代码,以防万一.我基本上只是制作一个程序来测试我的电脑的速度功能.
#include <iostream>
using namespace std;
#include <math.h>
int main()
{
float *bob = new float[50102133];
float *jim = new float[50102133];
float *joe = new float[50102133];
int i,j,k,l;
//cout << "Starting test...";
for (i=0;i<50102133;i++)
bob[i] = sin(i);
for (j=0;j<50102133;j++)
bob[j] = sin(j*j);
for (k=0;k<50102133;k++)
bob[k] = sin(sqrt(k));
for (l=0;l<50102133;l++)
bob[l] = cos(l*l);
cout << "finished test.";
cout << "the 100120 element is," << bob[1001200];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
最明显的选择是使用OpenMP.假设您的循环是一个非常容易并行执行多次迭代的循环,您可能只需添加:
#pragma openmp parallel for
Run Code Online (Sandbox Code Playgroud)
...紧接在循环之前,让它并行执行.-fopenmp编译时还需要添加.
根据循环的内容,这可能会提供几乎线性加速的任何地方,从而稍微降低代码速度.在后一种情况下(减速或最小加速),你可以用OpenMP做其他事情来帮助加快速度,但是至少不知道代码本身,很难猜测你该做什么或者你可能有什么改进能够达到最大值.
你得到的其他建议("使用线程")可能是合适的.OpenMP基本上是一种将线程用于特定类型的并行代码的自动方式.对于你描述的情况(并行执行循环的多次迭代),OpenMP通常是首选的 - 它实现起来相当简单,并且可能会提供更好的性能,除非你非常了解多线程和/或花费很多努力并行化代码.
编辑:
您在问题中提供的代码可能不会受益于多个线程.问题是在将结果写入内存之前,它对每个数据项执行的计算非常少.即使是单核也可能足够快地进行计算,总速度将受到内存带宽的限制.
为了从多个线程获得一些真正的好处,您可能想要编写一些代码来执行更多计算,而不仅仅是读取和写入内存.例如,如果我们将您的计算合并在一起,并在单个项目上执行所有计算,则将结果相加:
double total = 0;
for (int i = 0; i < size; i++)
total += sin(i) + sin(i*i) + sin(sqrt(i)) + cos(i*i);
Run Code Online (Sandbox Code Playgroud)
添加一个pragma:
#pragma omp parallel for reduction(+:total)
Run Code Online (Sandbox Code Playgroud)
......就在for循环之前,我们很有可能看到执行速度的显着提高.没有OpenMP,我会得到这样的时间:
Real 16.0399
User 15.9589
Sys 0.0156001
Run Code Online (Sandbox Code Playgroud)
...但是#pragma在编译时启用了OpenMP,我得到这样的时间:
Real 8.96051
User 17.5033
Sys 0.0468003
Run Code Online (Sandbox Code Playgroud)
因此,在我的(双核)处理器上,时间从16秒减少到9秒 - 不是快两倍,但非常接近.当然,您获得的许多改进将取决于您可用的核心数量.例如,在我的另一台计算机上(使用Intel i7 CPU),我得到了相当大的改进,因为它有更多内核.
没有OpenMP:
Real 15.339
User 15.3281
Sys 0.015625
Run Code Online (Sandbox Code Playgroud)
...和OpenMP:
Real 3.09105
User 23.7813
Sys 0.171875
Run Code Online (Sandbox Code Playgroud)
为了完整性,这是我使用的最终代码:
#include <math.h>
#include <iostream>
static const int size = 1024 * 1024 * 128;
int main(){
double total = 0;
#pragma omp parallel for reduction(+:total)
for (int i = 0; i < size; i++)
total += sin(i) + sin(i*i) + sin(sqrt(i)) + cos(i*i);
std::cout << total << "\n";
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4715 次 |
| 最近记录: |