【问题标题】:Multiple pragmas directives on for loop (C and VS 2013)for 循环上的多个编译指示指令(C 和 VS 2013)
【发布时间】:2015-09-11 13:12:26
【问题描述】:

我正在尝试使用 OpenMP 将 for 循环计算拆分为多个线程。此外,我试图指示编译器对分配给每个线程的每个块进行矢量化。代码如下:

#pragma omp for private(i)
__pragma(loop(ivdep))
for (i = 0; i < 4096; i++)
    vC[i] = vA[i] + SCALAR * vB[i];

问题在于,两个编译指示都希望紧接着 for 循环。

是否有任何智能结构可以使这项工作发挥作用?

有些人可能会争辩说,由于使用 OpenMP 的 for 循环拆分,循环的矢量化将不起作用。但是我读到 #pragma omp for 将循环划分为多个与线程数相等的连续块。 是吗?

【问题讨论】:

    标签: c visual-studio optimization openmp vectorization


    【解决方案1】:

    使用 #pragma omp for simd private(i) 代替 pragma + __pragma() 怎么样?

    编辑:由于 OpenMP 4 似乎不适合您,您可以手动拆分循环以摆脱#pragma omp for,只需使用omp_get_num_threads()omp_get_thread_num() 手动计算索引限制,然后为每个线程循环保留ivdep

    编辑 2:因为我是一个好人,而且这是样板文件(在 MPI 中编程时更常见,但仍然如此)但是当你第一次做它时很烦人,这是一个可能的解决方案:

    #pragma omp parallel
    {
        int n = 4096;
        int tid = omp_get_thread_num();
        int nth = omp_get_num_threads();
        int chunk = n / nth;
        int beg = tid * chunk + min( tid, n % nth );
        int end = ( tid + 1 ) * chunk + min( tid + 1, n % nth );
        #pragma ivdep
        for ( int i = beg; i < end; i++ ) {
            vC[i] = vA[i] + SCALAR * vB[i];
        }
    }
    

    【讨论】:

    • 我会,但似乎 VS2013 无法识别“simd”openmp 令牌
    • 也许您可以尝试安装/使用更新的编译器,支持 OpenMP 4.0。 GCC 可以,例如可以使用 cygwin 安装。英特尔编译器也可以,并且可免费用于非商业用途。
    • 我知道英特尔编译器生成更好的代码,我不再需要#pragma 循环。但是我现在只有 VS CL,我希望能快速修复。
    猜你喜欢
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    相关资源
    最近更新 更多