我可以报告openmp任务的进度吗? [英] Can I report progress for openmp tasks?

查看:156
本文介绍了我可以报告openmp任务的进度吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一个经典的OMP任务:

Imagine a classic OMP task:

  • 对范围为[0.0,1.0)的double的大向量求和

在Coliru上直播

using namespace std;

int main() {
    vector<double> v;

    // generate some data
    generate_n(back_inserter(v), 1ul << 18, 
       bind(uniform_real_distribution<double>(0,1.0), default_random_engine { random_device {}() }));

    long double sum = 0;

    {
#pragma omp parallel for reduction(+:sum)
        for(size_t i = 0; i < v.size(); i++)
        {
            sum += v[i];
        }
    }
    std::cout << "Done: sum = " << sum << "\n";
}

我很难想出如何报告进度的想法.毕竟,OMP正在为我处理团队线程之间的所有协调,而我没有一个全局状态.

I have trouble coming up with an idea how to report progress. After all, OMP is handling all the coordination between team threads for me, and I don't have a piece of global state.

我可能会使用常规的std::thread并从那里观察一些共享变量,但是难道没有实现这种目标的麻烦"方法吗?

I could potentially use a regular std::thread and observe some shared variable from there, but isn't there a more "omp-ish" way to achieve this?

推荐答案

只需让团队中的每个线程跟踪本地进度并自动更新全局计数器.您仍然可以让另一个线程对其进行观察,或者,如下面的示例所示,您可以只在OMP关键部分内进行终端输出.

Just let each thread in the team track local progress and update a global counter atomically. You could still make another thread observe it, or, as in my sample below, you could just do the terminal output within an OMP critical section.

此处的关键是调整不会导致频繁更新的逐步大小,因为对关键区域(以及较小程度的原子加载/存储)的锁定会降低性能. /em>

The key here is to tune for a stepsize that doesn't lead to highly frequent updates, because then the locking for the critical region (and to a lesser extent the atomic load/stores) would degrade performance.

在Coliru上直播

#include <omp.h>
#include <vector>
#include <random>
#include <algorithm>
#include <iterator>
#include <functional>
#include <iostream>
#include <iomanip>

using namespace std;

int main() {
    vector<double> v;
    // generate some data
    generate_n(back_inserter(v), 1ul << 18, bind(uniform_real_distribution<double>(0,1.0), default_random_engine { random_device {}() }));

    auto step_size   = 100ul;
    auto total_steps = v.size() / step_size + 1;

    size_t steps_completed = 0;
    long double sum = 0;

#pragma omp parallel 
    {
        size_t local_count = 0;


#pragma omp for reduction(+:sum)
        for(size_t i = 0; i < v.size(); i++)
        {
            sum += v[i];

            if (local_count++ % step_size == step_size-1)
            {
#pragma omp atomic
                ++steps_completed;

                if (steps_completed % 100 == 1)
                {
#pragma omp critical
                    std::cout << "Progress: " << steps_completed << " of " << total_steps << " (" << std::fixed << std::setprecision(1) << (100.0*steps_completed/total_steps) << "%)\n";
                }
            }
        }
    }
    std::cout << "Done: sum = " << sum << "\n";
}

最后,打印结果.输出:

Finally, print the result. Output:

Progress: 1 of 2622 (0.0%)
Progress: 191 of 2622 (7.3%)
Progress: 214 of 2622 (8.2%)
Progress: 301 of 2622 (11.5%)
Progress: 401 of 2622 (15.3%)
Progress: 501 of 2622 (19.1%)
Progress: 601 of 2622 (22.9%)
Progress: 701 of 2622 (26.7%)
Progress: 804 of 2622 (30.7%)
Progress: 901 of 2622 (34.4%)
Progress: 1003 of 2622 (38.3%)
Progress: 1101 of 2622 (42.0%)
Progress: 1201 of 2622 (45.8%)
Progress: 1301 of 2622 (49.6%)
Progress: 1402 of 2622 (53.5%)
Progress: 1501 of 2622 (57.2%)
Progress: 1601 of 2622 (61.1%)
Progress: 1701 of 2622 (64.9%)
Progress: 1801 of 2622 (68.7%)
Progress: 1901 of 2622 (72.5%)
Progress: 2001 of 2622 (76.3%)
Progress: 2101 of 2622 (80.1%)
Progress: 2203 of 2622 (84.0%)
Progress: 2301 of 2622 (87.8%)
Progress: 2402 of 2622 (91.6%)
Progress: 2501 of 2622 (95.4%)
Progress: 2601 of 2622 (99.2%)
Done: sum = 130943.8

这篇关于我可以报告openmp任务的进度吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆