j'ai le code suivant (the xorshift128+
code from Wikipedia modifié pour utiliser les types de vecteurs):Mon vectorisé xorshift + est pas très aléatoire
#include <immintrin.h>
#include <climits>
__v8si rand_si() {
static auto s0 = __v4du{4, 8, 15, 16},
s1 = __v4du{23, 34, 42, 69};
auto x = s0, y = s1;
s0 = y;
x ^= x << 23;
s1 = x^y^(x >> 17)^(y >> 26);
return (__v8si)(s1 + y);
}
#include <iostream>
#include <iomanip>
void foo() {
//Shuffle a bit. The result is much worse without this.
rand_si(); rand_si(); rand_si(); rand_si();
auto val = rand_si();
for (auto it = reinterpret_cast<int*>(&val);
it != reinterpret_cast<int*>(&val + 1);
++it)
std::cout << std::hex << std::setfill('0') << std::setw(8) << *it << ' ';
std::cout << '\n';
}
qui délivre en sortie
09e2a657 000b8020 1504cc3b 00110040 1360ff2b 00150078 2a9998b7 00228080
tout autre nombre est très faible, et aucun n'a le premier bit défini. D'autre part, en utilisant xorshift * au lieu:
__v8si rand_si() {
static auto x = __v4du{4, 8, 15, 16};
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
return x * (__v4du)_mm256_set1_epi64x(0x2545F4914F6CDD1D);
}
je reçois la meilleure sortie
0889632e a938b990 1e8b2f79 832e26bd 11280868 2a22d676 275ca4b8 10954ef9
Mais selon Wikipedia, xorshift + est une bonne PRNG, et produit une meilleure pseudo-aléatoire que xorshift * . Alors, ai-je un bug dans mon code RNG, ou est-ce que je l'utilise mal?
Vous construisez avec 'clang', non? [gcc dit] (https://godbolt.org/g/qLUFuz) *
@PeterCordes, Oui, c'est correct. – Dan
Pourquoi utilisez-vous '__v8si' et' __v4du' à la place des types standard définis par Intel? –