使g++;生成一个可以使用多核的程序? 我有一个多循环的C++程序;每一次运行大约500万次迭代。是否有任何命令可以与g++一起使用,以使生成的.exe将使用多个内核;i、 e.在第一个磁芯上同时运行第一个For循环,在第二个磁芯上同时运行第二个For循环?我已经尝试过-O3和-O3-ftree矢量化,但在这两种情况下,我的cpu使用率仍然只有25%左右

使g++;生成一个可以使用多核的程序? 我有一个多循环的C++程序;每一次运行大约500万次迭代。是否有任何命令可以与g++一起使用,以使生成的.exe将使用多个内核;i、 e.在第一个磁芯上同时运行第一个For循环,在第二个磁芯上同时运行第二个For循环?我已经尝试过-O3和-O3-ftree矢量化,但在这两种情况下,我的cpu使用率仍然只有25%左右,c++,gcc,optimization,g++,core,C++,Gcc,Optimization,G++,Core,编辑: 这是我的代码,以防万一。我基本上只是做一个程序来测试我电脑的速度能力 #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 <

编辑: 这是我的代码,以防万一。我基本上只是做一个程序来测试我电脑的速度能力

#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;
}
#包括
使用名称空间std;
#包括
int main()
{
浮动*bob=新浮动[50102133];
浮动*jim=新浮动[50102133];
浮动*乔=新浮动[50102133];
int i,j,k,l;

/c/Out[P>C++ 11有支持,但C++编译器自己不能/不做任何线程。

最明显的选择是使用OpenMP。假设循环是一个很容易并行执行多个迭代的,你可以只添加:

#pragma openmp parallel for
…并使其并行执行。编译时还必须添加
-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);
…就在
for
循环之前,我们很有可能看到执行速度有了实质性的提高。如果没有OpenMP,我的时间如下:

Real    16.0399
User    15.9589
Sys     0.0156001
Real    8.96051
User    17.5033
Sys     0.0468003
…但在编译时启用了
#pragma
和OpenMP,我得到的时间如下:

Real    16.0399
User    15.9589
Sys     0.0156001
Real    8.96051
User    17.5033
Sys     0.0468003
因此,在我的(双核)处理器上,时间从16秒下降到了9秒——速度不是原来的两倍,但非常接近。当然,您获得的许多改进将取决于可用的内核数量。例如,在我的另一台计算机上(使用Intel i7 CPU),我得到了相当大的改进,因为它有更多的内核

没有OpenMP:

Real    15.339
User    15.3281
Sys     0.015625
…并使用OpenMP:

Real    3.09105
User    23.7813
Sys     0.171875
为了完整起见,以下是我使用的最终代码:

#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";
}
#包括
#包括
静态常量int size=1024*1024*128;
int main(){
双倍合计=0;
#pragma omp并行减少(+:总计)
对于(int i=0;istd::cout编译器无法判断循环中的代码是否可以安全地在多个核上执行。如果要使用所有核,请使用线程。

使用线程或进程,您可能需要像其他人指出的那样,手动使用线程来实现这一点。您可以查看库,例如(aka.GCD)或者用最少的痛苦来帮助你做到这一点

您提到的
-ftree vectorize
选项用于定位CPU上的向量处理器单元,如ARM的NEON或Intel的SSE。生成的代码不是线程并行的,而是使用单个线程进行操作并行的

上面发布的代码示例非常适合SIMD系统上的并行性,因为每个循环的主体显然不依赖于上一次迭代,并且循环中的操作是线性的


至少在某些ARM Cortex A系列系统上,您可能需要接受稍微降低的精度才能获得全部好处。

为什么不使用线程?有点相关:谢谢!我尝试了您的优化代码,通过优化,我能够在30秒内运行约50亿次计算(而没有-fopenmp,则几乎需要2分钟),而原始的内存密集型程序每秒迭代约500万次。