【问题标题】:OpenMP: Share single-threaded and multi-threaded implementations of the same algorithmOpenMP:共享同一算法的单线程和多线程实现
【发布时间】:2019-08-29 04:40:04
【问题描述】:

我在一个代码库中工作,其中几个算法被实现了两次:一次在正确的位置使用#pragma omp parallel,一次没有。这些函数被命名为AlgorithmMT()AlgorithmST()

简化示例:

/// Multi-threaded algorithm
std::vector<double>
AlgorithmMT(int n)
{
    std::vector<double> result(n);
    std::itoa(result.begin(), result.end(), 1.0);
#pragma omp parallel for
    for (int i = 0; i < n; ++i) {
        result[i] = i / result[i];
    }
    return result;
}

/// Single-threaded algorithm
std::vector<double>
AlgorithmST(int n)
{
    std::vector<double> result(n);
    std::itoa(result.begin(), result.end(), 1.0);
// NOTE: there is no #pragma here
    for (int i = 0; i < n; ++i) {
        result[i] = i / result[i];
    }
    return result;
}

假设我需要保留两个单独的函数(不能更改更高级别的代码),并且应该允许用户在运行时在它们之间进行选择,我怎样才能让这两个函数共享一个共同的实现?

我意识到该算法有点荒谬,并且可以在没有读取依赖于循环内的result 的情况下实现。请假设这是算法所需的结构。 :)

【问题讨论】:

    标签: c++ multithreading openmp


    【解决方案1】:

    一种简洁的方法是使用parallel 构造的if 子句,例如:

    bool is_parallel = ...;
    #pragma omp parallel for if (is_parallel)
    

    这是在运行时评估的,并且每个定义具有产生单个线程的相同效果。

    这种运行时区别与省略pragma 并不完全相同,编译器可能会以不同方式优化代码。虽然我不会太担心,但你应该观察你的表现。只需在没有-fopenmp 的情况下编译应用程序,并将性能与动态禁用的并行性进行比较。 如果存在差异,您可能不得不求助于冗余代码或以某种方式帮助编译器。请注意,性能可能因编译器而异。

    【讨论】:

    • 这看起来很棒。我试试看!
    【解决方案2】:

    您可以使用 OpenMP 运行时 API 中的 omp_set_num_threads 在并行部分之前将线程计数限制为 1,然后在该部分之后将其恢复。

    警告:如果已经有其他并行线程在运行,那么omp_set_num_threads 也会影响那里的并行部分。

    【讨论】:

      【解决方案3】:

      因为#pragma 是预处理器,所以你不能做很多事情。 你可以用你的函数创建algorithm.cpp.part,但用%parallel%代替#pragma omp for,然后在编译时,在makefile中用类似这样的东西替换文本:

      sed '/%parallel%/c\#pragma omp parallel'  algorithm.cpp.part > algorithm_mt.cpp
      sed '/%parallel%/c\ '  algorithm.cpp.part > algorithm_st.cpp
      

      如果你有很多这样的函数,它可以通过良好的 makefile 规则进行相对较好的扩展。

      或者,如果您正在为 Windows 编译,您可以使用并发运行时,它会避免使用 #pragma,这在您的情况下可能很有用。

      (这个答案不要太苛刻,我在手机上写这个)

      【讨论】:

      • 您可以在运行时更改最大线程数,有效地使代码单线程。
      • 但如果多个线程需要不同的设置,可能会导致问题。无论如何,我们的两个答案都是 hack,真的可能导致更大的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-13
      • 2012-09-04
      • 1970-01-01
      • 2021-12-17
      相关资源
      最近更新 更多