gpt4 book ai didi

performance - OpenMP程序性能低下

转载 作者:行者123 更新时间:2023-12-04 03:16:52 24 4
gpt4 key购买 nike

我试图从here理解openmp代码。您可以在下面看到代码。


为了测量速度,串行版本和omp版本之间的差异,我使用time.h,您找到合适的方法吗?
该程序在4核计算机上运行。我指定export OMP_NUM_THREADS="4"但看不到明显的加速,通常我得到1.2-1.7。我在并行化中面临哪些问题?
我可以使用哪个调试/性能工具来查看性能损失?


代码(对于编译,我使用xlc_r -qsmp=omp omp_workshare1.c -o omp_workshare1.exe

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#define CHUNKSIZE 1000000
#define N 100000000

int main (int argc, char *argv[])
{
int nthreads, tid, i, chunk;
float a[N], b[N], c[N];
unsigned long elapsed;
unsigned long elapsed_serial;
unsigned long elapsed_omp;
struct timeval start;
struct timeval stop;


chunk = CHUNKSIZE;

// ================= SERIAL start =======================
/* Some initializations */
for (i=0; i < N; i++)
a[i] = b[i] = i * 1.0;
gettimeofday(&start,NULL);
for (i=0; i<N; i++)
{
c[i] = a[i] + b[i];
//printf("Thread %d: c[%d]= %f\n",tid,i,c[i]);
}
gettimeofday(&stop,NULL);
elapsed = 1000000 * (stop.tv_sec - start.tv_sec);
elapsed += stop.tv_usec - start.tv_usec;
elapsed_serial = elapsed ;
printf (" \n Time SEQ= %lu microsecs\n", elapsed_serial);
// ================= SERIAL end =======================


// ================= OMP start =======================
/* Some initializations */
for (i=0; i < N; i++)
a[i] = b[i] = i * 1.0;
gettimeofday(&start,NULL);
#pragma omp parallel shared(a,b,c,nthreads,chunk) private(i,tid)
{
tid = omp_get_thread_num();
if (tid == 0)
{
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
//printf("Thread %d starting...\n",tid);

#pragma omp for schedule(static,chunk)
for (i=0; i<N; i++)
{
c[i] = a[i] + b[i];
//printf("Thread %d: c[%d]= %f\n",tid,i,c[i]);
}

} /* end of parallel section */
gettimeofday(&stop,NULL);
elapsed = 1000000 * (stop.tv_sec - start.tv_sec);
elapsed += stop.tv_usec - start.tv_usec;
elapsed_omp = elapsed ;
printf (" \n Time OMP= %lu microsecs\n", elapsed_omp);
// ================= OMP end =======================
printf (" \n speedup= %f \n\n", ((float) elapsed_serial) / ((float) elapsed_omp)) ;

}

最佳答案

上面的代码并没有什么真正的问题,但是您的速度将受到以下事实的限制:主循环c = a + b的工作量很少-计算所需的时间(一次累加)内存访问时间(2个负载和一个存储)将决定内存的使用,并且随着更多的线程作用在阵列上,内存带宽的争用将更多。

我们可以通过使循环内的工作更加计算密集来进行测试:

c[i] = exp(sin(a[i])) + exp(cos(b[i]));


然后我们得到

$ ./apb

Time SEQ= 17678571 microsecs
Number of threads = 4

Time OMP= 4703485 microsecs

speedup= 3.758611


这显然比人们期望的4倍加速快得多。

更新:哦,还有其他问题-gettimeofday()可能适合计时,并且在使用xlc的系统上-这是AIX吗?在这种情况下,peekperf是一个很好的整体性能工具,并且硬件性能监视器将使您可以访问内存访问时间。在x86平台上,用于监视线程代码的性能的免费工具包括用于调试缓存性能(此处不是问题)的cachegrind / valgrind,用于一般OpenMP问题的scalasca,以及OpenSpeedShop也非常有用。

关于performance - OpenMP程序性能低下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4512237/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com