【问题标题】:CHUNKSIZE in openMP static schedulingopenMP 静态调度中的 CHUNKSIZE
【发布时间】:2021-03-18 16:56:30
【问题描述】:

假设我的代码的每次循环迭代都需要相同的时间。
请注意,每次循环迭代都涉及从大型连续内存的不相交部分进行内存访问。
我正在使用 VS2019 编译器。

我认为我是否使用无关紧要

#pragma omp for schedule(static, CHUNKSIZE)

#pragma omp for schedule(static)

我对 CHUNKSIZE 使用了 5 之类的值。 我问这个是因为我发现第一个变体的表现要好一些。
有人可以发光吗?

【问题讨论】:

    标签: c multithreading parallel-processing openmp scheduling


    【解决方案1】:

    如果不指定块

    #pragma omp for schedule(static)
    

    OpenMP 将:

    将循环分成大小相等的块或在 循环迭代次数不能被整除的情况 线程数乘以块大小。 默认情况下,块 大小为 loop_count/number_of_threads

    因此,对于 CHUNKSIZE=52 threads 和带有 22 迭代的循环(要并行化)。 thread ID=0 将分配迭代 {0 to 10}thread ID=1 {11 to 21}。每个线程都有11 迭代。但是,对于:

    #pragma omp for schedule(static, CHUNKSIZE)
    

    thread ID=0 将分配迭代{0 to 4}{10 to 14}{20 to 21},而thread ID=1 将使用迭代{5 to 9}{15 to 19}。因此,它分别被分配给第一个和第二个线程1210 迭代。

    这一切都表明拥有

    #pragma omp for schedule(static)
    

     #pragma omp for schedule(static, CHUNKSIZE)
    

    不一样。不同的块大小可能会直接影响loading balancing 和缓存未命中等。即使一个:

    假设我的代码的每个循环迭代都花费相同的时间

    如果被并行化的循环的每次迭代都在执行不同的工作,那么想法自然会变得更加复杂。例如:

    for(int i = 0; i < 22; i++)
      for(int j = i+1; j < 22 ; i++)
         // do the same work.
    

    #pragma omp for schedule(static)
    

    Thread ID=0 将执行 176 迭代,而 Thread ID=1 55。负载不平衡为 176 - 55 = 121

    #pragma omp for schedule(static, CHUNKSIZE)
    

    Thread ID=0 将执行 141 迭代和 Thread ID=1 90。负载不平衡为 141 - 90 = 51

    您可以在没有块的情况下看到,一个线程执行121 并行任务比另一个线程多,而使用chunk=5,差异减少到51

    总而言之,这取决于您的代码、执行代码的硬件、执行基准测试的方式、时间差有多大等等。底线是:您需要对其进行分析,寻找潜在的负载平衡问题,测量缓存未命中等。分析始终是答案。

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 2015-08-15
      • 2012-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      相关资源
      最近更新 更多