我在通过多个线程生成随机数时遇到了性能问题。这是所有线程使用相同随机引擎的原因。然后我实现了一个包含每个线程的随机引擎的向量(在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。 我想念一下吗?
答案 0 :(得分:1)
首先,如果你有两个内核和超线程,它看起来像你的代码的四个处理器,但它不是速度的四倍,只比你幸运的两倍快一点。
其次,如果您使用所有CPU电源,计算机将升温然后降低时钟速度。
第三,您可能正在使用具有巨大状态的随机数。一个状态可以适合L1缓存,但不适用于其中四个的状态。这可能会导致巨大的放缓。
第四,你有一个变量&#34; counter&#34;在线程之间共享并在每次迭代时读取。这不会很快。