for 循环上的多个编译指示指令(C 和 VS 2013)

Posted

技术标签:

【中文标题】for 循环上的多个编译指示指令(C 和 VS 2013)【英文标题】:Multiple pragmas directives on for loop (C and 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 将循环划分为多个与线程数相等的连续块。 是吗?

【问题讨论】:

【参考方案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,我希望能快速修复。

以上是关于for 循环上的多个编译指示指令(C 和 VS 2013)的主要内容,如果未能解决你的问题,请参考以下文章

OSX forrange 循环上的 C++ VS 代码

for(;;)和while(true)的区别

尽管有一次编译指示,VS2012 仍抱怨“已定义”类

链接 vs 编译 vs 控制器

喵呜:C++基础系列:auto关键字(C++11)基于范围的for循环(C++11)指针空值nullptr(C++11)

喵呜:C++基础系列:auto关键字(C++11)基于范围的for循环(C++11)指针空值nullptr(C++11)