升压随机和OpenMP [英] Boost Random and OpenMP

查看:104
本文介绍了升压随机和OpenMP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我越来越从code的OpenMP并行段总线错误。我重新低于我的问题的一个简单的版本。在code基本上使许多人呼吁使用Boost的uniform_int_distribution其中提请0和20000之间的整数功能 uniform_distribution

帖子警告两个线程访问同一个对象。我猜这就是在我的情况。 (不幸的是,我不知道怎么写一个合适的互斥体包装,因为该职位建议)。

一个可能的肮脏的解决方案我认为是要建立一个本地的#pragma为循环和内传递作为参数传递给 uniform_distribution 。因为在我的实际code,我打电话许多功能,并通过当地的,我不喜欢这个主意会很麻烦。另外,我担心的是,不同的线程将生成的相同随机数序列如果我声明 uniform_distribution 。所以,我有两个要求:怎样的方式并行化


  1. 每个线程生成概率独立于其他线程借鉴?

  2. 发生在RNG没有竞争条件?

感谢;任何帮助是热烈AP preciated。

 的#include< omp.h>
#包括LT&;升压/随机/ uniform_int_distribution.hpp>提高::随机:: mt19937工程;INT uniform_distribution(INT rangeLow,诠释rangeHigh){
    提高::随机:: uniform_int_distribution< INT> unirv(rangeLow,rangeHigh);
    返回unirv(ENG);
}
诠释的main()
{
    #编译OMP私人(ENG)并行
    对于(INT BB = 0; BB< 10000; BB ++)
        的for(int i = 0; I< 20000;我++)
             INT A = uniform_distribution(0,20000);    返回0;
}


解决方案

在并行约code,你必须考虑共享资源,这可能会导致的数据竞争的,反过来,最终可能会破坏你的程序。 (注:并非所有的数据竞争将打破你的程序)

在你的情况,正如你正确预期,是由两个或更多的线程,它必须避免为正确执行共享。

一个为你的情况的解决方案是的私有化:让每个线程副本的共享资源。您需要创建一个单独的副本

有一个数量的方式做私有化

(1)尽量使用 THREADPRIVATE 指令(的链接):例如,的#pragma OMP THREADPRIVATE(ENG)。然而,一些编译器可能不支持非POD结构此指令。

(2)情况下 THREADPRIVATE 不可用,用数组和线程ID访问:声明如 ENG [MAX_THREAD] 。然后,线程ID访问: ENG [omp_get_thread()]

然而,在第二解决方案需要考虑的伪共享的,这会严重损害的性能。这是最好的保证每个项目ENG [MAX_THREAD] 是在单独的缓存行边界,这是典型的现代台式机CPU的64字节分配。也有几种方法,以避免错误共享。最简单的解决办法是使用填充:例如,字符填充[X] 结构持有

I'm getting a "bus error" from an OpenMP parallel section of code. I recreated a simple version of my problem below. The code essentially makes many calls to the function uniform_distribution, which draws an integer between 0 and 20000 using Boost's uniform_int_distribution.

This post warns of two threads accessing the same object. I'm guessing that's eng in my case. (Unfortunately I don't know how to write "an appropriate mutex wrapper", as that post suggests).

A possible dirty solution I thought of was to create a local eng inside the #pragma for loop and to pass that as an argument to uniform_distribution. I don't like this idea because in my real code, I'm calling many functions, and passing a local eng would be cumbersome. Also, my concern is that different threads will generate the same random number sequence if I declare eng inside uniform_distribution. So I have two requirements: How do I parallelize in a way that

  1. Each thread is generating probabilistically independent draws from other threads?
  2. No race conditions occur on the RNG?

Thanks; any help is warmly appreciated.

#include <omp.h>
#include <boost/random/uniform_int_distribution.hpp>

boost::random::mt19937  eng;

int uniform_distribution(int rangeLow, int rangeHigh) {
    boost::random::uniform_int_distribution<int> unirv(rangeLow, rangeHigh);
    return unirv(eng);
}
int main()
{  
    # pragma omp parallel for private(eng)
    for (int bb=0; bb<10000; bb++)
        for (int i=0; i<20000; i++)
             int a = uniform_distribution(0,20000);

    return 0;
}

解决方案

When you parallelize some code, you must consider the shared resource, which can cause data races, in turn, eventually may break your program. (Note: not all data races will break your program.)

In your case, as you expected correctly, eng is the shared by two or more threads, which must be avoided for the correct execution.

A solution for your case is privatization: making a per-thread copy for the shared resources. You need to create a separate copy of eng.

There are a number of way to do privatization for eng:

(1) Try to use threadprivate directive (link): For example, #pragma omp threadprivate(eng). However, some compilers may not support non-POD structures for this directive.

(2) In case where threadprivate is not available, use an array of eng and access with thread id: declare such as eng[MAX_THREAD]. Then, access with thread id: eng[omp_get_thread()].

However, the second solution needs to consider false sharing, which can severely hurt the performance. It's best to guarantee each item in eng[MAX_THREAD] is allocated on separate cache line boundary, which is typically 64-byte in modern desktop CPUs. There are also several ways to avoid false sharing. The simplest solution would be using padding: e.g., char padding[x] in a struct that holds eng.

这篇关于升压随机和OpenMP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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