在 C++ 项目中使用 openmp 时没有观察到加速

问题描述 投票:0回答:1

我尝试将并行执行添加到我的 C++ 项目中。

因此,基于这个例子我定义了我的

app.cpp
如下:

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

int sum_serial(int n) {
    int sum = 0;
    for (int i = 0; i <= n; ++i) {
        sum += i;
    }
    return sum;
}

// Parallel programming function
int sum_parallel(int n) {
    int sum = 0;
#pragma omp parallel for reduction(+ : sum)
    for (int i = 0; i <= n; ++i) {
        sum += i;
    }
    return sum;
}

int main(int argc, char* argv[]) {
    // Beginning of parallel region
#pragma omp parallel
    { printf("Hello World... from thread = %d\n", omp_get_thread_num()); }
    // Set threads number.
#if defined(_OPENMP)
    omp_set_num_threads(2);
#endif

    {
        const int n = 100000000;

        auto start_time = std::chrono::high_resolution_clock::now();

        int result_serial = sum_serial(n);

        auto end_time = std::chrono::high_resolution_clock::now();

        std::chrono::duration<double> serial_duration = end_time - start_time;

        start_time = std::chrono::high_resolution_clock::now();

        int result_parallel = sum_parallel(n);
        end_time = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double> parallel_duration = end_time - start_time;

        std::cout << "Serial result: " << result_serial << std::endl;
        std::cout << "Parallel result: " << result_parallel << std::endl;
        std::cout << "Serial duration: " << serial_duration.count() << " seconds" << std::endl;
        std::cout << "Parallel duration: " << parallel_duration.count() << " seconds" << std::endl;
        std::cout << "Speedup: " << serial_duration.count() / parallel_duration.count()
                  << std::endl;
    }
    return 0;
}

令我惊讶的是,没有加速,事实上,并行执行速度慢了很多。我的输出是:

Serial result: 987459712
Parallel result: 987459712
Serial duration: 0.132073 seconds
Parallel duration: 0.645815 seconds
Speedup: 0.204507

注意我的cmake是:

add_executable(wingdesigner app.cpp)
target_compile_features(app PRIVATE cxx_std_17)

add_compile_options(-Wall -O3 -fopenmp)


target_link_libraries(app PUBLIC gomp)

出了什么问题?

我一定做错了什么。我知道大量线程可能会导致几乎无法观察到的加速,但在这种特殊情况下,2 个线程比 1 个线程应该更快,对吧? 我认为我的编译是错误的,但我不知道问题出在哪里。

c++ cmake openmp
1个回答
0
投票

我尝试了你的示例,发现即使使用 OMP,也只使用了一个线程。

事实上,你的CMake文件似乎是错误的(应该使用

target_compile_options
而不是
add_compile_options
)。我使用了以下内容并观察到一些加速:

project (foobar)
add_executable(app app.cpp)
target_compile_features(app PRIVATE cxx_std_17)
target_compile_options (app PUBLIC -Wall -O3 -fopenmp)
target_link_libraries  (app PUBLIC gomp)

我还使用了以下代码片段(使用

sin
)以便有“更多”工作要做:

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

auto sum_serial(int n) {
    double sum = 0;
    for (int i = 0; i <= n; ++i) {
        sum += sin(i);
    }
    return sum;
}

// Parallel programming function
auto sum_parallel(int n) {
    double sum = 0;
#pragma omp parallel for reduction(+ : sum)
    for (int i = 0; i <= n; ++i) {
        sum += sin(i);
    }
    return sum;
}

int main(int argc, char* argv[]) {
    // Beginning of parallel region
#pragma omp parallel
    { printf("Hello World... from thread = %d\n", omp_get_thread_num()); }
    // Set threads number.
#if defined(_OPENMP)
    omp_set_num_threads(2);
#endif

    {
        const int n = 100000000;

        auto start_time = std::chrono::high_resolution_clock::now();

        auto result_serial = sum_serial(n);

        auto end_time = std::chrono::high_resolution_clock::now();

        std::chrono::duration<double> serial_duration = end_time - start_time;

        start_time = std::chrono::high_resolution_clock::now();

        auto result_parallel = sum_parallel(n);
        end_time = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double> parallel_duration = end_time - start_time;

        std::cout << "Serial result    : " << result_serial << std::endl;
        std::cout << "Parallel result  : " << result_parallel << std::endl;
        std::cout << "Serial duration  : " << serial_duration.count() << " seconds" << std::endl;
        std::cout << "Parallel duration: " << parallel_duration.count() << " seconds" << std::endl;
        std::cout << "Speedup          : " << serial_duration.count() / parallel_duration.count() << std::endl;
    }
    return 0;
}

我得到以下输出:

Serial result    : 1.71365
Parallel result  : 1.71365
Serial duration  : 1.08041 seconds
Parallel duration: 0.546919 seconds
Speedup          : 1.97545
© www.soinside.com 2019 - 2024. All rights reserved.