0

我正在向您发送一个关于多进程编程的玩具程序。程序运行良好与否我可以获得 50% 以上的性能。但是,如果我为程序输入 # pragma parallel 将不再起作用。怎样才能提高性能?我如何知道应该运行多少进程才能获得最佳性能。例如,在 4 核或 8 核上?:

#include <stdio.h>
#include <windows.h>
#include <process.h>          
#include <time.h>
#include <stdlib.h>

#define X 100000

char matrix[8000*X] ;
volatile long barrier = 0 ;

unsigned long long start[] ={ 0         ,   1000*X+1    ,   2000*X+1    ,   3000*X+1    ,   4000*X+1    ,   5000*X+1,   7000*X+1 } ;
unsigned long long stop[]  ={ 1000*X    ,   2000*X      ,   3000*X      ,   4000*X      ,   5000*X      ,   6000*X  ,   8000*X   } ;

 void  init( void *arg1 ) 
 {
  long i ;
  const long s0 = start[(ULONG_PTR)arg1];
  const long s1 = stop[(ULONG_PTR)arg1];

  // #pragma omp parallel for <------ *** with pragma does not work ! ***
  for (i= s0 ; i< s1 ; i++ )
  {
    matrix[i] = 0 ;
  }
  ++barrier ;
 }

long main()
{
   register long i , ZZZ;
   clock_t tempo0 ;
   clock_t tempo1 ;

   // ********************************************************#1
    printf( "Now in the main() function.\n" );
    tempo0 = clock();
    for (ZZZ=0;ZZZ<100;ZZZ++)
    {
                  for ( i=0;i<8000*X;i++)
                    matrix[i] = 0 ;
    }
    tempo1 = clock();
    printf ( "\nsequenziale <%lf>\n" , (double) tempo1-tempo0 );

    //  return 0 ;
    // ******************************************************* #2
    tempo0 = clock();
    for (ZZZ=0;ZZZ<100;ZZZ++)
    {   
        barrier = 0 ;
        _beginthread( init, 0, (void*) 0 );
        _beginthread( init, 0, (void*) 1 );
        _beginthread( init, 0, (void*) 2 );
        _beginthread( init, 0, (void*) 3 );
        _beginthread( init, 0, (void*) 4 );
        _beginthread( init, 0, (void*) 5 );
        _beginthread( init, 0, (void*) 6 );
        _beginthread( init, 0, (void*) 7 );

        while ( barrier!=8) 
        ;
    }

    tempo1 = clock ();

    printf ( "\nthread <%lf>\n" , (double) tempo1-tempo0 );


}

预先感谢

4

1 回答 1

0

首先,我要说的是,如果您查看您在顺序部分和线程部分中所做的工作,那是不一样的。因此,您的时间/性能比较实际上没有意义:

for (ZZZ=0;ZZZ<100;ZZZ++)
{
              for ( i=0;i<8000*X;i++)
                matrix[i] = 0 ;
}

您将 100 * 矩阵初始化为 0 但在线程代码中,您仅将矩阵初始化为 0 1 次!

现在为您的性能问题。

事实上,您在想要扩展的方式上犯了几个错误,这就是为什么当您取消注释时它最终不起作用的原因#pragma omp parallel for

想象一下,您的示例中有 8 个内核(每个内核 1 个线程)。在你的循环中

for (ZZZ=0;ZZZ<100;ZZZ++)
{   
    barrier = 0 ;
    _beginthread( init, 0, (void*) 0 );
    _beginthread( init, 0, (void*) 1 );
    _beginthread( init, 0, (void*) 2 );
    _beginthread( init, 0, (void*) 3 );
    _beginthread( init, 0, (void*) 4 );
    _beginthread( init, 0, (void*) 5 );
    _beginthread( init, 0, (void*) 6 );
    _beginthread( init, 0, (void*) 7 );

    while ( barrier!=8) 
    ;
}

8 个线程正在运行,现在如果您在init函数中取消注释 OpenMp 指令,您会要求 openMP 将每个 init 函数的作业拆分为多个 (8) 线程。

所以现在理论上你有 8x8 线程并发运行,但你只有 8 个核心。这就是为什么它不起作用。由于所有的胎面上下文切换,性能会下降!

事实上,现在回答您的最后一个问题,“我如何知道应该运行多少进程才能获得最佳性能?”,

  1. 我们谈论线程,而不是进程!
  2. ZZZ 循环是您的粗粒度,因此它是可以使用 openMp 的循环。
  3. OpenMP 将在您的核心 4、8、16 等上免费拆分您的 100 次迭代。

所以我将重写你的代码,如下所示:

tempo0 = clock();
#pragma omp parallel for
for (int z = 0 ; z < 8000*X ; z++)
{  
matrix[z] = 0;
}
tempo1 = clock ();

我只有 2 个核心但没有 OpenMP,它需要 630 个滴答声,只有 452 个有 2 个核心,它会随着更多核心自动下降。

于 2013-07-21T18:50:40.830 回答