簡體   English   中英

采樣條件分布 OpenMP

[英]Sampling conditional distribution OpenMP

我有一個隨機抽取樣本的函數:

Sample sample();

我有一個功能可以檢查樣本是否有效:

bool is_valid(Sample s);

這模擬了條件分布。 現在我想要很多有效的樣本(大多數樣本都無效)。

所以我想用 openMP 並行化這段代碼

vector<Sample> valid_samples;
while(valid_samples.size() < n) {
    Sample s = sample();
    if(is_valid(s)) {
        valid_samples.push_back(s);
    }
}

我該怎么做? 我發現的大多數 OpenMP 代碼都是簡單的for循環,其中迭代次數是在開始時確定的。

sample()函數有一個

thread_local std::mt19937_64 gen([](){
    std::random_device d;
    std::uniform_int_distribution<int> dist(0,10000);
    return dist(d);
}());

作為隨機數生成器。 如果我假設我的設備具有隨機源,那么它是否有效並且線程保存? 有更好的解決方案嗎?

您可以使用 OpenMP任務並行性 最簡單的解決方案是將任務定義為單個樣本插入:

vector<Sample> valid_samples(n); // need to be resized to allow access in parallel

void insert_ith(size_t i)
{
  do {
    valid_samples[i] = sample();
  } while (!is_valid(valid_samples[i]));
}

#pragma omp parallel
{
  #pragma omp single
  {
    for (size_t i = 0; i < n; i++) 
    {
      #pragma omp task
      insert_ith(i);
    }
  }
}

請注意,此類單任務單插入映射可能存在性能問題。 首先,會涉及錯誤共享,但可能更糟的是,任務管理有一些開銷,這對於非常小的任務可能很重要。 在這種情況下,補救方法很簡單——不是每個任務一次插入,而是一次插入多個項目,例如 100。通常,合適的數字是一種權衡:越低創建的任務越多 = 開銷越大,越高可能會導致更糟糕的負載平衡。

您需要處理代碼中的關鍵部分,即插入到答案向量中

像這樣的東西應該可以工作(因為沒有給出函數和類型,所以沒有編譯)

// create vector before parallel section because it shall be shared
vector<Sample> valid_samples(n); // set initial size to avoid reallocation
int reached_count = 0;
#pragma omp parallel shared(valid_samples, n, reached_count)
{
    while(reached_count < n) { // changed this, see comments for discussion
        Sample s = sample(); // I assume this to be thread indepent
        if(is_valid(s)) {
            #pragma omp critical
            {
                // check condition again, another thread might have already
                // reached maximum number
                if(reached_count < n) {
                    valid_samples.push_back(s);
                    reached_count = valid_samples.size();
                }
            }
        }
    }
}

請注意, sample()isvalid(s)都不在臨界區內,因為我認為這些函數比向量插入要昂貴得多,或者接受率非常低

如果不是這種情況,您可以使用獨立的局部向量並最終合並,但是如果您以某種方式減少同步次數,例如提供固定數量的迭代(至少對於很大一部分)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM