Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 为什么随机数生成器在并行执行时会导致问题?_Multithreading_Performance_Random_Parallel Processing - Fatal编程技术网

Multithreading 为什么随机数生成器在并行执行时会导致问题?

Multithreading 为什么随机数生成器在并行执行时会导致问题?,multithreading,performance,random,parallel-processing,Multithreading,Performance,Random,Parallel Processing,我有一项任务,其中提到以下内容: 并行性增加了更多的复杂性,如随机数 当两个或多个线程调用时,生成器函数必须正确运行 同时,它必须是线程安全的 然而,我不明白为什么这首先是一个问题。随机生成器通常以种子作为参数进行调用,并通过对其执行多个操作来输出一个数字。我知道我们需要每个线程使用不同的种子,但除此之外,问题从何而来?我已经意识到,在并行区域而不是串行区域中生成和调用随机生成器也确实会降低性能,但我不理解为什么会发生这种情况,因为从外观上看,随机数生成器应该并发运行,没有任何问题,因为它们没有

我有一项任务,其中提到以下内容:

并行性增加了更多的复杂性,如随机数 当两个或多个线程调用时,生成器函数必须正确运行 同时,它必须是线程安全的

然而,我不明白为什么这首先是一个问题。随机生成器通常以种子作为参数进行调用,并通过对其执行多个操作来输出一个数字。我知道我们需要每个线程使用不同的种子,但除此之外,问题从何而来?我已经意识到,在并行区域而不是串行区域中生成和调用随机生成器也确实会降低性能,但我不理解为什么会发生这种情况,因为从外观上看,随机数生成器应该并发运行,没有任何问题,因为它们没有依赖关系


理解这背后的理论方面的任何帮助都将不胜感激。

除了从竞争条件中获取错误值之外(由@MitchWheat指出),由于主流x86处理器上内核之间的缓存线共享,代码的效率将降低

下面是一个(非常糟糕但很简单)32位随机生成器的示例(用C编写):

uint32\u t seed=0xD1263AA2;
uint32_t customRandom(){
uint32_t old=种子;
种子=(uint32_t)((uint64_t)种子*0x2E094C40)>>24);
返老还童;
}
无效生成值(uint32*arr,大小){

对于(size_t i=0;iif 2个或更多线程尝试写回已存储的生成器“状态”,可以在不锁定的情况下发生争用条件,但就我的基本理解而言,这可以解释错误的结果,但不会导致性能降低(我知道添加锁会降低性能,但我只是说代码处于初始状态,没有修复它)几乎在所有情况下,任何时候在线程之间存储和共享写入状态,都必须进行同步以保持正确性。我考虑了性能问题,因为并行调用随机生成器时会遇到性能问题,与串行调用和使用其结果相比,性能大约差2.5倍并行的lt(显然这不是一个好方法,因为所有线程都使用相同的随机数,我正在使用蒙特卡罗方法)非常感谢您的回答。我对缓存一致性问题很熟悉,因为我已经研究了使用pthreads的错误共享,我记得使用padding解决了这个问题,在使用OpenMP之类的工具时,如果没有对随机生成器做任何更改,有没有方法来解决这个问题?或者有人会直接运行随机生成器serial?@Sergio No.AFAIK,OpenMP不提供任何控制全局变量的方法(我不确定是否有库可以,但编译器理论上可以)。通常的解决方案是用提供给生成器的局部变量替换隐藏的全局状态。全局变量通常不好,原因很多,包括性能(即使在顺序代码中)和软件工程。您应该避免像瘟疫这样的可变全局变量。另一种解决方案是将变量
thread\u local
同时放在C11和C++11中。非常感谢