OpenMP(GCC编译器)中的默认计划

时间:2020-05-06 15:14:07

标签: c++ gcc openmp

我在C ++程序中使用OpenMP。根据gcc文档,默认调度为dynamic,块大小为1-> https://gcc.gnu.org/onlinedocs/gcc-9.3.0/libgomp.pdf(p22)。

我决定对此进行测试,因此我编写了一个简单的C ++测试程序:

#include <chrono>
#include <cmath>
#include <iostream>
#include <omp.h>
#include <vector>


int main()
{
    std::vector<double>  myArray {};
    for(std::size_t i {0} ; i < 100000000 ; ++i)
    {
        myArray.push_back(static_cast<double>(i));
    }

    #pragma omp parallel
    {
        if(omp_get_thread_num() == 0)
        {
            std::cout << "Number of threads = " << omp_get_num_threads() << "/" << omp_get_num_procs() << std::endl;
            omp_sched_t schedule {};
            int chunk_size {};
            omp_get_schedule(&schedule , &chunk_size);
            std::string scheduleStr {};
            switch(schedule)
            {
                case omp_sched_static:
                    scheduleStr = "static";
                    break;
                case omp_sched_dynamic:
                    scheduleStr = "dynamic";
                    break;
                case omp_sched_guided:
                    scheduleStr = "guided";
                    break;
                case omp_sched_auto:
                    scheduleStr = "auto";
                    break;
                default:
                    scheduleStr = "monotonic";
                    break;
            }
            std::cout << "Default schedule: " << scheduleStr << "," << chunk_size << std::endl;;
        }
    }

    auto startTime {std::chrono::high_resolution_clock::now()};
    #pragma omp parallel for default(shared) schedule(dynamic, 1)
    for(std::size_t i = 0 ; i < myArray.size() ; ++i)
    {
        myArray[i] = std::pow(myArray[i], 10);
    }
    auto endTime {std::chrono::high_resolution_clock::now()};
    auto ellapsedTime {std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime)};
    std::cout << "OMP for Time: " << static_cast<double>(ellapsedTime.count())/1000.0 << " s" << std::endl;

    return 0;
}

我使用MSYS2的mingw版本(gcc 9.3.0)编译了代码,没有进行优化,并且启用了-g。如文档中所述,默认计划为dynamic, 1。但是,我计算机上的计算时间为(具有2个线程):

  • with schedule(static):〜2.103s
  • 带有schedule(dynamic, 1):〜24.096s
  • 省略schedule(应为dynamic, 1):〜2.101s

因此默认的时间表似乎是static!我知道我在问一个非常具体的问题,但这是预期的行为吗?

2 个答案:

答案 0 :(得分:2)

OMP_SCHEDULEomp_set_schedule()影响运行时循环调度,即for带有schedule(runtime)子句的构造。在大多数OpenMP运行时中,不存在schedule子句时的默认调度为static,其块大小等于#iterations / #threads(处理#threads不除{ {1}}是特定于实现的,但是其余的迭代通常分布在前#iterations个线程上。在这种情况下,考虑到开销,没有明智的OpenMP供应商会选择#iterations % #threads作为默认设置。

答案 1 :(得分:-1)

p 22:3.12 OMP_SCHEDULE –如何调度线程描述:允许指定调度类型和块大小。变量的值应采用以下形式:type [,chunk],其中type是静态,动态,引导或自动之一。可选的块大小应为正整数。如果未定义,则使用动态调度且块大小为1。

您引用的这一部分是关于环境变量的。如果未定义环境变量,则使用动态调度和块大小为1。在您的代码中,您不会检查该环境变量的值或存在性,而只会检查实际的调度策略。如果您确实检查了环境变量,那么我希望它确实存在并且设置为静态。具体操作方式取决于操作系统(在Linux中为printenv)。

相关问题