【问题标题】:Why does OpenMP speed up a SINGLE-ITERATION loop?为什么 OpenMP 会加速 SINGLE-ITERATION 循环?
【发布时间】:2019-08-01 05:04:48
【问题描述】:

我正在使用来自Why is writing to memory much slower than reading it? 的“读取”基准,我只添加了两行:

#pragma omp parallel for
for(unsigned dummy = 0; dummy < 1; ++dummy) 

它们应该没有效果,因为OpenMP should only parallelize the outer loop,但现在代码运行速度始终快两倍。

更新:这些行甚至不是必需的。只需添加

omp_get_num_threads();

(隐式声明)在同一个地方有同样的效果。

完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

unsigned long do_xor(const unsigned long* p, unsigned long n)
{
    unsigned long i, x = 0;

    for(i = 0; i < n; ++i)
        x ^= p[i];
    return x;
}

int main()
{
    unsigned long n, r, i;
    unsigned long *p;
    clock_t c0, c1;
    double elapsed;

    n = 1000 * 1000 * 1000; /* GB */
    r = 100; /* repeat */

    p = calloc(n/sizeof(unsigned long), sizeof(unsigned long));

    c0 = clock();

#pragma omp parallel for
    for(unsigned dummy = 0; dummy < 1; ++dummy) 
    for(i = 0; i < r; ++i) {
        p[0] = do_xor(p, n / sizeof(unsigned long)); /* "use" the result */
        printf("%4ld/%4ld\r", i, r);
        fflush(stdout);
    }

    c1 = clock();

    elapsed = (c1 - c0) / (double)CLOCKS_PER_SEC;

    printf("Bandwidth = %6.3f GB/s (Giga = 10^9)\n", (double)n * r / elapsed / 1e9);

    free(p);
}

编译和执行
gcc -O3 -Wall -fopenmp single_iteration.c && time taskset -c 0 ./a.out

time 报告的挂墙时间是 3.4s vs 7.5s。

GCC 7.3.0 (Ubuntu)

【问题讨论】:

  • 我可以复制。它不是优化或clock 的问题。不过,我建议您可以通过测量墙上时间并添加实际测量结果以及您的 CPU 和内存规格来改进问题。

标签: c performance gcc memory openmp


【解决方案1】:

造成性能差异的原因实际上并不是代码上的任何差异,而是内存映射方式的差异。在快速情况下,您正在从零页面读取,即所有虚拟地址都映射到单个物理页面 - 因此无需从内存中读取任何内容。在缓慢的情况下,它不会归零。详情见this answer from a slightly different context

另一方面,它不是由调用 omp_get_num_threads 或 pragma 本身引起的,而只是链接到 OpenMP 运行时库。您可以使用-Wl,--no-as-needed -fopenmp 进行确认。如果您只指定-fopenmp 但根本不使用它,链接器将忽略它。

现在不幸的是,我仍然错过了最后一块拼图:为什么链接到 OpenMP 会改变 calloc 关于零页面的行为。

【讨论】:

  • -fopenmp 可能使用不同的(线程安全)版本的calloc
猜你喜欢
  • 2012-11-13
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多