【问题标题】:Bottleneck at random number generation with multiple threads多线程随机数生成瓶颈
【发布时间】:2023-04-04 04:56:01
【问题描述】:

我在通过多个线程生成随机数时遇到了性能问题。这是对所有线程使用相同随机引擎的原因。然后我实现了一个向量,其中包含每个线程的随机引擎(在 stackoverflow 上的另一篇文章中找到了这个解决方案)。但我希望每秒的迭代次数会随着我正在执行的线程数线性增长。但这似乎并非如此。

这是一个最小的例子:

#include <random>
#include <omp.h>

const int threads = 4;

int main()
{
    std::uniform_int_distribution<uint64_t> uint_dist;
    std::vector<std::mt19937_64> random_engines;
    std::random_device rd;

    for (int i = 0;i < threads;i++)
        random_engines.push_back(std::mt19937_64((rd())));

    omp_set_num_threads(threads);

    int counter = 0;
    #pragma omp parallel for
    for (int i = 0;i < threads;++i)
    {
        int thread = omp_get_thread_num();
        while (counter < 100)
        {
            if (uint_dist((random_engines[thread])) < (1ULL << 42))
                counter++;
        }
    }
}

在使用一个活动线程执行此代码时,我的 CPU 上的平均执行时间约为 4 秒。将线程设置为 4 使我的平均执行时间约为 2 秒,因此线程数的乘数为 4,最终加速为 2。 我错过了什么吗?

【问题讨论】:

  • counter 的同步存在潜在问题:线程相互阻塞,或者读取-修改-写入不是原子的,并且某些写入通常会丢失。我对 OpenMP 的了解还不够,无法说出更可能的情况。

标签: c++ multithreading random


【解决方案1】:

首先,如果您有两个内核和超线程,那么您的代码看起来就像是四个处理器,但速度不是四倍,如果幸运的话,只比两倍快一点。

其次,如果您使用所有 CPU 电源,您的计算机会发热,然后降低时钟速度。

第三,你可能使用了一个状态巨大的随机数。一个的状态可能适合 L1 缓存,但不适合其中四个的状态。这可能会导致巨大的放缓。

第四,您有一个变量“计数器”,它在线程之间共享并在每次迭代时读取。这不会很快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多