【问题标题】:I need help creating a minimal example showing openMP speed-up on my system我需要帮助创建一个在我的系统上显示 openMP 加速的最小示例
【发布时间】:2012-02-24 19:54:21
【问题描述】:

因此,在我之前尝试使用 openMP 之后,我意识到我没有任何代码示例在并行化时与串行相比在我的系统上实际上运行得更快。下面是一个尝试(失败)的简短示例,首先显示确实有两个内核,并且 openMP 正在使用它们,然后对两个脑死任务进行计时,一个使用 openMP,另一个不使用。 我正在测试的任务很可能有问题,所以如果有人能提出另一个健全性测试,我将不胜感激,这样我就可以亲眼看到多线程可以工作:)

#include <iostream>
#include <vector>
#include <ctime>
#include <cmath>

using namespace std;

#include <omp.h>

int main(int argc, char *argv[])
{


    //Below code will be run once for each processor (there are two)
    #pragma omp parallel 
    {
        cout << omp_get_thread_num() << endl; //this should output 1 and 0, in random order
    }


    //The parallel example:
    vector <double> a(50000,0);

    clock_t start = clock();
#pragma omp parallel for  shared(a) 
    for (int i=0; i < 50000; i++)    
    {
        double StartVal=i;

        for (int j=0; j<2000; ++j)
            a[i]=(StartVal + log(exp(exp((double) i)))); 
    } 

    cout<< "Time: " << ( (double) ( clock() - start ) / (double)CLOCKS_PER_SEC ) <<endl;

    //The serial example:
    start = clock();

    for (int i=0; i < 50000; i++)    
    {
        double StartVal=i;

        for (int j=0; j<2000; ++j)
            a[i]=(StartVal + log(exp(exp((double) i)))); 
    } 

    cout<< "Time: " << ( (double) ( clock() - start ) / (double)CLOCKS_PER_SEC ) <<endl;

    return 0;
}

输出是:

    1
    0
    Time: 4.07
    Time: 3.84

这可能与 openMP 缺少的 forloop 优化有关吗?还是我测量时间的方式有问题?在这种情况下,您对不同的测试有什么想法吗?

提前谢谢你:)

编辑: 事实证明,我测量时间的方式很糟糕。使用omp_get_wtime(),输出变为:

1
0
Time: 4.40776
Time: 7.77676

我想我最好回去再看看我的老问题......

【问题讨论】:

    标签: c++ openmp


    【解决方案1】:

    我能想到两种可能:

    1. 如果您在 Linux 上运行。 clock() 不测量 Linux 上的挂墙时间。它测量 CPU 时间。
      我建议您改用 omp_get_wtime()
    2. 您的测试不够大。尝试将2000 增加到200000 之类的值。

    这是我在 Windows 上使用200000 内部循环迭代得到的结果:

    4
    5
    2
    3
    1
    6
    7
    0
    Time: 1.834
    Time: 6.792
    

    我对@9​​87654321@ 的回答有一个非常简单的 OpenMP 示例,可以实现加速。

    【讨论】:

      【解决方案2】:

      正如 Mystical 所说,这也许就是您衡量的方式。在 linux 中你可以使用clock_gettime。 使用具有 4 个内核(我有 6 个物理内核)的 linux 虚拟机,即使内部循环小到 j

      #include <sys/time.h>
      
      int main( ... ) ... same as your code ...    
         timespec ts1;
         timespec ts2;
      
         //start measurement:
         clock_gettime(CLOCK_REALTIME, &ts1);
      
         ... code to time here ...
      
         //stop measurement:
      
         clock_gettime(CLOCK_REALTIME, &ts2);
      
         cout<< "clock Time s: " << (ts2.tv_sec-ts1.tv_sec) + 1e-9*( ts2.tv_nsec-ts1.tv_nsec ) <<endl;
      
        ... }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多