OpenMP 一次只执行一个线程

OpenMP executes only one thread at a time

本文关键字:一个 线程 执行 一次 OpenMP      更新时间:2023-10-16

这是我的代码:

template <unsigned int DIM>
MyVector<DIM> MyVector<DIM>::operator+(MyVector& other) {
    MyVector ans = MyVector<DIM>();
    #pragma omp parallel for
    for (unsigned int i = 0; i < DIM; ++i)
    {
        std::cout << omp_get_thread_num() << std::endl;
        ans.values_[i] = values_[i] + other.values_[i];
    }
    return ans;
}

其中values_是双精度模板化的 std::vector,DIM 类似于 1024。

我使用'g++ -std=c++14 -fopenmp -g'编译了它

。当我

不使用 OpenMP 时,即使我有多个线程,我获得的性能也几乎没有区别。

确实,这句话:

std::cout << omp_get_thread_num() << std::endl;

显示线程一次执行一个...

输出很干净,类似于 11111...、22222...、00000...、33333...,htop 始终只显示一个 100% 的核心,在整个执行过程中是相同的。

我已经在几台具有多个发行版的机器上尝试过,它到处都是一样的。

您可能希望像这样重写代码,以防止 I/O 的巨大开销(也或多或少地序列化程序执行):

template <unsigned int DIM>
MyVector<DIM> MyVector<DIM>::operator+(MyVector& other) {
    MyVector ans = MyVector<DIM>();
    #pragma omp parallel
    {
        #pragma omp critical(console_io)
        {
            // The following are actually two function calls and a critical
            // region is needed in order to ensure I/O atomicity
            std::cout << omp_get_thread_num() << std::endl;
        }
        #pragma omp for schedule(static)
        for (unsigned int i = 0; i < DIM; ++i)
        {
            ans.values_[i] = values_[i] + other.values_[i];
        }
    }
    return ans;
}

确保DIM既足够大,以便 OpenMP 的开销与正在完成的工作相比较小,同时又足够小,使向量适合 CPU 的最后一级缓存。一旦后者不再适用,您的循环就会受到内存限制,添加新线程不会加快计算速度。

相关文章: