【问题标题】:OpenMP C++ GCC Basic routineOpenMP C++ GCC 基本例程
【发布时间】:2015-09-04 10:09:17
【问题描述】:

我正在使用 openMP 在 C++ 中运行一个非常简单的例程并测量经过的时间......代码在读取时进行,

#include <iostream>
#include <math.h>
#include "timer.h"
#include <omp.h>



int main ()
{
    double start,finish;
    int i;
    int n=8000;
    double a[n];
    double b[n];
    double c[n];



    GET_TIME(start);
#pragma omp parallel private(i,a) shared(b,c,n)
    {
#pragma omp for 
        for (i=0; i<n-1; i++)
        b[i] += (a[i] + a[i+1])/2;
#pragma omp for
        for (i=0; i<n-1; i++)
            c[i] += (a[i] + a[i+1])/2;
    } 
    GET_TIME(finish);
    std::cout<< "Elapsed time is" <<(finish-start)<<"seconds";
    return 0;
}

我正在使用以下 bash 脚本编译代码(注意线程是在环境变量 OMP_NUM_THREADS=$n 中定义的):

#!/bin/bash

clear

g++ -O3 -o test test.cpp -fopenmp 

for n in $(seq 1 8); do
  export OMP_NUM_THREADS=$n
   ./test
    echo threads=$n
done

因此,随着线程数量的增加,性能下降的总体趋势如下:(当然数量可以改变)......

Elapsed time is0.000161886secondsthreads=1
Elapsed time is0.00019002secondsthreads=2
Elapsed time is0.00226498secondsthreads=3
Elapsed time is0.000210047secondsthreads=4
Elapsed time is0.000212908secondsthreads=5
Elapsed time is0.00920105secondsthreads=6
Elapsed time is0.00937104secondsthreads=7
Elapsed time is0.000834942secondsthreads=8

对提高性能(而不是降低性能)有何建议? 非常感谢!

【问题讨论】:

  • 如果我正确阅读了您的数字,当从 7 个线程变为 8 个线程时,执行速度会提高 10 倍以上——性能显着提高。我建议您使用更大更长的循环重新计时,并在尝试得出任何结论之前平均运行 3 到 5 次。
  • 谢谢马克。。也许我最常得到的是: 8.39233e-05secondsthreads=1 已用时间 is0.000119925secondsthreads=2 已用时间 is0.000138044secondsthreads=3 已用时间 is0.000138044secondsthreads=4 已用时间is0.000123978secondsthreads=5 已用时间 is0.000133991secondsthreads=6 已用时间 is0.00356102secondsthreads=7 已用时间 is0.00615597secondsthreads=8....当我增加线程时总是变得更糟...我知道 Loop 不够大,但是有没有办法用 SIMD f.e. 等其他技术来改进它?谢谢!。

标签: c++ bash gcc openmp hpc


【解决方案1】:

你可以这样做,它会增加每个线程完成的操作。这是为了通过实际让线程执行更多工作来克服启动新线程所需的开销。此外,无需将 b、c 或 n 声明为共享。

#pragma omp parallel private(i,a,b,c,n)
{
#pragma omp for schedule(static)
    for (i=0; i<n-1; i++){
        b[i] += (a[i] + a[i+1])/2;
        c[i] += (a[i] + a[i+1])/2;}
}

【讨论】:

  • 谢谢,但仍然降低性能...看...经过的时间是3.38554e-05secondsthreads=1经过的时间是0.000103951secondsthreads=2经过的时间是0.000139952secondsthreads=3经过的时间是0。 000194788secondsthreads=4 经过时间是0.000201225secondsthreads=5 经过时间是0.000176191secondsthreads=6 经过时间是0.000298023secondsthreads=7 经过时间是0.000277996secondsthreads=8
  • 尝试使用静态调度。我已经修改了答案以包含它。您的测试很小,不同试验的结果差异很大。
  • 再次感谢您!结果,实际上会有所不同,因为这是一个小问题,但是始终使用一个内核比使用更多内核要快得多...我尝试了您的帖子所读的内容,随着线程的增加而变得越来越糟...谢谢! .经过时间is8.39233e-05secondsthreads = 1个经过时间is0.000119925secondsthreads = 2个经过时间is0.000138044secondsthreads = 3个经过时间is0.000138044secondsthreads = 4个经过时间is0.000123978secondsthreads = 5个经过的时间is0.000133991secondsthreads = 6个经过时间is0.00356102secondsthreads = 7 经过的时间是0.00615597secondsthreads=8
  • 这是HPC中经常出现的问题。并行计算有很多好处,但您需要了解您的代码在多大程度上可以扩展到更多数量的处理器。在短期运行时,您的性能提升通常会被创建额外线程/进程的开销所消耗。线程/进程之间的通信,以及共享资源(如内存或磁盘)上的额外负载。使用 Mido 的优化代码想出一个需要几秒钟才能完成的运行,看看随着线程数的增加,数字是否看起来更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多