增加线程数减少时间

Posted

技术标签:

【中文标题】增加线程数减少时间【英文标题】:increase number of threads decrease time 【发布时间】:2014-03-22 19:06:40 【问题描述】:

我是 openmp 的新手。从openmp官方页面的教程开始 https://www.youtube.com/playlist?list=PLLX-Q6B8xqZ8n8bwjGdzBJ25X2utwnoEG

在该页面中有一个 hello world 程序通过近似积分来计算 pi。 我只是按照说明编写了下面的代码,但它的时间速度随着我增加更改 NUM_THREADS 的线程数而增加。在视频中,速度下降了。

我正在远程服务器上执行程序,该服务器有 64 个 CPU,每个 CPU 有 8 个内核。

#include <stdio.h>
#include <omp.h>
static long num_steps = 100000;
double step;

#define NUM_THREADS 2 

int main()

    int i, nthreads; double pi, sum[NUM_THREADS];
    double start_t;

    step = 1.0 / (double) num_steps;

    omp_set_num_threads(NUM_THREADS);

    start_t = omp_get_wtime();
    #pragma omp parallel
    
        int i, id, nthrds;
        double x;

        id = omp_get_thread_num();
        nthrds = omp_get_num_threads();
        if (id == 0) nthreads = nthrds;
        for (i = id, sum[id] = 0.0; i < num_steps; i = i + nthrds) 
            x = (i + 0.5) * step;
            sum[id] += 4.0 / (1.0 + x*x);
        
    
    for (i = 0, pi = 0.0; i < nthreads; i++) 
        pi += sum[i] * step;
    
    printf("%f\n", omp_get_wtime() - start_t);

【问题讨论】:

你的意思是8核8线程的远程服务器吗? 是的,8 核每核 8 个线程。 【参考方案1】:

这是使用共享数组实现归约的一种不好的方法。 sum 的连续元素彼此太接近,因此驻留在同一缓存行中。在像 x86/x64 这样的缓存一致架构上,这会导致一个称为错误共享的问题。下面简单的修改就可以去掉它:

double sum[8*NUM_THREADS];

#pragma omp parallel

    ...
    for (i = id, sum[id] = 0.0; i < num_steps; i = i + nthrds) 
        ...
        sum[8*id] += 4.0 / (1.0 + x*x);
    

for (i = 0, pi = 0.0; i < nthreads; i++) 
    pi += sum[8*i] * step;

仅显示相关更改。这个想法很简单:不是让线程访问sum 的连续元素,而是让它们访问每8 个元素。因此,可以保证线程不会共享与大多数现代 CPU 相同的高速缓存行,高速缓存行的长度为 64 字节,对应于 64 / sizeof(double) = 8 个数组元素。

编辑:我的错误,应该首先观看视频。在显示运行代码的结果之后解释虚假共享。如果您的情况没有得到任何加速,那可能是因为较新的 CPU 代可以更好地处理错误共享。

【讨论】:

如果您要进行缩减,您应该让 OpenMP 通过使用“omp 并行”上的“缩减”子句为您完成。这样你就不必担心它的实现,只需让每台机器上的实现来做正确的事情,你就完全不需要全局数组了。 reduction 子句稍后出现;) 我们的教学风格不同:-)。我会在讨论缓存问题之前解释归约,因为归约是一个高级(语义)概念,而缓存问题是低级的,将我们带入硬件的实现问题。对于那些回答“解释机器代码?”的人是“嗯,有一个叫做 Java 虚拟机的东西”,当他们的问题可以通过“让编译器为你做缩减”来解决时,你会因为跳跃到缓存争用而咬牙切齿。 我有什么资格与蒂姆·马特森的教学风格争论? :) 原来代码是故意这样写的,随后就引入了虚假共享。

以上是关于增加线程数减少时间的主要内容,如果未能解决你的问题,请参考以下文章

执行时间取决于使用 OpenMP 库增加的线程数?

线程总是在增加

设置最佳线程数总结

控制并行循环中的线程数并减少开销

如何增加tomcat线程池中的线程数?

Tomcat设置最佳线程数总结