Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.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
C++ CPU内部并行化_C++_C_Performance_Prng - Fatal编程技术网

C++ CPU内部并行化

C++ CPU内部并行化,c++,c,performance,prng,C++,C,Performance,Prng,我一直在玩Xorshift*随机数生成器,我偶然发现了它们的特性。从该站点(重点矿山)引用: XorShift 64*生成器如何比XorShift 1024*生成器慢 依赖关系。xorshift64*生成器的三个xor/移位必须顺序执行,因为每一个移位都取决于前一个移位的结果。在xorshift1024*生成器中,两个xor/移位是完全独立的,可以由CPU内部并行化。我还怀疑,较大的状态空间使CPU能够执行更积极的推测性执行(实际上,xorshift128*生成器比xorshift1024*生成

我一直在玩Xorshift*随机数生成器,我偶然发现了它们的特性。从该站点(重点矿山)引用:

XorShift 64*生成器如何比XorShift 1024*生成器慢

依赖关系。xorshift64*生成器的三个xor/移位必须顺序执行,因为每一个移位都取决于前一个移位的结果。在xorshift1024*生成器中,两个xor/移位是完全独立的,可以由CPU内部并行化。我还怀疑,较大的状态空间使CPU能够执行更积极的推测性执行(实际上,xorshift128*生成器比xorshift1024*生成器慢)

CPU语句内部的并行化意味着什么?我认为这意味着CPU将使用向量指令同时执行两个xor/移位,但我在编译器的汇编输出中没有看到这方面的证据。这是一个很深的CPU流水线吗?或者我应该能够在生成的汇编程序中看到一些事情发生吗?

是的,这是一件事

基本上,这样的CPU将拥有比每条指令所需的更多的执行硬件,因此它将一组指令“分散”到可用资源上,然后将结果合并回来,这样对程序员来说,事情看起来仍然是按顺序发生的

如果你擅长的话,你能看到的是两条相邻的指令,它们都可以工作,但没有依赖性。例如,它们可能仅在不重叠的寄存器集上操作。对于这种情况,您可以猜测它们可能是并行执行的,从而导致特定代码位的高指令/周期值

为了让这更具体一点,让我们看一下您正在谈论的两段代码(还有:我的学习机会)

以下是xorshift64*的核心:

x ^= x >> 12; // a
x ^= x << 25; // b
x ^= x >> 27; // c
return x * 2685821657736338717LL;

这里,全局状态位于
uint64\t s[16],p
变量中。考虑到这一点,可能并不十分清楚,但至少有点暗示,带有
//c
注释的行没有与前面的行共享任何状态。因此,它同时进行移位和异或运算(即“功”),而异或运算独立于之前所做的类似功。因此,超标量处理器可能或多或少能够并行运行这两行。

具有多个执行单元和较长的管道-减少串行依赖性可以通过让更多执行单元保持忙碌来实现更高的并行性。因此,如果你有两个ALU,如果你让它们都忙的话,你可以得到两倍的吞吐量。一个CPU在一个代码/线程中有多个执行端口。当指令之间没有依赖关系时,可以在同一时钟上运行多条指令。这不是编译时生成的并行性,而是CPU在运行时生成的并行性,当它看到一个块中的多条指令没有依赖关系时。顺便说一句,这种CPU并行性称为指令级并行性。@didierc那么如何使CPU看到更多独立的指令呢?它们不是编译时生成的吗?删除不必要的依赖项不是编译器的工作吗?我认为这是ILP,流水线和超标量只是实现ILP的方法。还有其他方法,如OoO和VLIW,也被广泛使用。@user3528438售出!谢谢但是VLIW不是假设编译器选择指令来实现并行性,而不是指令“看起来”是顺序的,但实际上是并行的吗?我认为,这里有某种不同……的确,VLIW不太适合原始问题。
uint64_t s0 = s[ p ];
uint64_t s1 = s[ p = ( p + 1 ) & 15 ];
s1 ^= s1 << 31; // a
s1 ^= s1 >> 11; // b
s0 ^= s0 >> 30; // c
return ( s[ p ] = s0 ^ s1 ) * 1181783497276652981LL;