我正在努力制作尽可能最快的高质量 RNG。读过http://xorshift.di.unimi.it/ http://xorshift.di.unimi.it/,xorshift128+ 似乎是一个不错的选择。 C代码是
#include <stdint.h>
uint64_t s[ 2 ];
uint64_t next(void) {
uint64_t s1 = s[ 0 ];
const uint64_t s0 = s[ 1 ];
s[ 0 ] = s0;
s1 ^= s1 << 23; // a
return ( s[ 1 ] = ( s1 ^ s0 ^ ( s1 >> 17 ) ^ ( s0 >> 26 ) ) ) + s0; // b, c
}
遗憾的是,我不是 SSE/AVX 专家,但我的 CPU 支持 SSE4.1 / SSE4.2 / AVX / F16C / FMA3 / XOP 指令。您如何使用这些来加速此代码(假设您想要生成数十亿个此类随机数)以及在实践中这种加速的预期限制是什么?
对于任何其他可能遇到这个问题的人,我认为这个 C++ 代码使用 AVX2 正确实现了并行运行的 4 个 xorshift128plus 生成器:
__m256i xorshift128plus_avx2(__m256i &state0, __m256i &state1)
{
__m256i s1 = state0;
const __m256i s0 = state1;
state0 = s0;
s1 = _mm256_xor_si256(s1, _mm256_slli_epi64(s1, 23));
state1 = _mm256_xor_si256(_mm256_xor_si256(_mm256_xor_si256(s1, s0),
_mm256_srli_epi64(s1, 18)),
_mm256_srli_epi64(s0, 5));
return _mm256_add_epi64(state1, s0);
}
我使用的标量实现是:
u64 xorshift128plus(u64 &state0, u64 &state1)
{
u64 s1 = state0;
const u64 s0 = state1;
state0 = s0;
s1 ^= s1 << 23; // a
state1 = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5); // b, c
return state1 + s0;
}
哪一个是同一个xorshiftplus纸 http://vigna.di.unimi.it/ftp/papers/xorshiftplus.pdf。请注意,原始问题中的右移常数与论文中的常数不对应。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)