在OpenMP中启动多少个线程?

3

我刚接触OpenMP编程,已经在GCC上运行了几个OpenMP示例程序。我想知道如何决定启动多少个线程(即如何决定omp_set_num_threads()函数的参数),以在双核英特尔处理器上获得更好的性能。

*这是我的示例程序*

#include<math.h>

#include<omp.h>
#include<stdio.h>
#include<time.h>
#define CHUNKSIZE 10
#define N 100000
#define num_t 10

void main ()  
{
    int runTime;
    int i, chunk;
    int a[N], b[N], c[N],threads[num_t];
    int thread_one=0,thread_two=0;
    clock_t start,end;
    omp_set_num_threads(num_t); 
    /* Some initializations */
    for (i=0; i < N; i++)
    a[i] = b[i] = i + 2.0;
    chunk = CHUNKSIZE;
        #pragma omp parallel shared(a,b,c,chunk,threads) private(i)
    {

            #pragma omp for schedule(dynamic,chunk)
            for (i=0; i < N; i++)
            {
                c[i] = pow((a[i] * b[i]),10);
                threads[omp_get_thread_num()]++;

            }
    }  /* end of parallel section */
    for(i=-1;i<num_t;i++)
    printf("Thread no %d : %d\n",i,threads[i]);
}

这是唯一的解决方案吗?如果我只启动2个线程,它不会在双核机器上提供更好的性能吗?我真的很新,需要知道这是如何工作的。 - Voila
是的,这是找出给定程序在给定机器上的最佳设置的唯一方法。核心/线程数量是一个好的起点,但是要尝试更多和更少的设置。对于某些问题,内存和内存带宽也很重要,所以CPU数量并不是唯一需要考虑的因素。 - Mat
2
如果您没有任何特殊知识,那么就让实现决定。 - David Schwartz
谢谢Mat和David,你们的回答非常有帮助。 - Voila
提示:将“动态”调度更改为“静态”,可以获得一些性能提升。 - Hristo Iliev
显示剩余2条评论
3个回答

3
作为一个经验法则,首次尝试将线程数设置为您计算机的核心数。然后尝试减少此数字以查看是否有任何改进。
顺便说一下,与其使用omp_set_num_threads,设置OMP_NUM_THREADS环境变量更方便进行这样的测试。

3

我的建议是:不必费心。如果这是一个计算密集型的应用程序(openmp主要用于此类应用程序,这也是你在这里使用它的原因),那么库本身将会很好地管理一切。


0

最佳线程数取决于许多参数,很难制定一个通用的经验法则。

对于计算密集型任务和低获取/计算比率,最好将线程数设置为等于CPU核心数。

对于重度内存绑定任务,增加线程数可能会在线程数等于核心数之前饱和内存带宽。循环向量化可以显著影响单个线程的内存带宽。在某些情况下,线程在CPU缓存中共享大量数据,但在某些情况下,它们不共享,并且增加它们的数量会减少可用的缓存空间。此外,NUMA系统通常提供比SMP更好的带宽。

在某些情况下,使用比核心更多的线程可以实现最佳性能-当每个任务内观察到大量阻塞等待时为真。有时SMT或HyperThreading可以隐藏内存延迟,有时不能,这取决于正在执行的内存访问类型。

除非您可以模拟代码性能并猜测最佳线程数,否则请尝试使用几个值进行实验。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接