Что ж, поскольку я не видел ссылки на старый добрый регистр сдвига с линейной обратной связью, я публикую некоторый внутренний код на основе SSE. Просто для комплектации. Я написал это пару месяцев назад, чтобы снова отточить свои навыки SSE.
#include <emmintrin.h>
static __m128i LFSR;
void InitRandom (int Seed)
{
LFSR = _mm_cvtsi32_si128 (Seed);
}
int GetRandom (int NumBits)
{
__m128i seed = LFSR;
__m128i one = _mm_cvtsi32_si128(1);
__m128i mask;
int i;
for (i=0; i<NumBits; i++)
{
// generate xor of adjecting bits
__m128i temp = _mm_xor_si128(seed, _mm_srli_epi64(seed,1));
// generate xor of feedback bits 5,6 and 62,61
__m128i NewBit = _mm_xor_si128( _mm_srli_epi64(temp,5),
_mm_srli_epi64(temp,61));
// Mask out single bit:
NewBit = _mm_and_si128 (NewBit, one);
// Shift & insert new result bit:
seed = _mm_or_si128 (NewBit, _mm_add_epi64 (seed,seed));
}
// Write back seed...
LFSR = seed;
// generate mask of NumBit ones.
mask = _mm_srli_epi64 (_mm_cmpeq_epi8(seed, seed), 64-NumBits);
// return random number:
return _mm_cvtsi128_si32 (_mm_and_si128(seed,mask));
}
Перевод этого кода на ассемблер тривиален. Просто замените встроенные функции настоящими инструкциями SSE и добавьте цикл вокруг них.
Кстати - последовательность, которую этот код генерирует, повторяется после 4.61169E + 18 чисел. Это намного больше, чем вы получите с помощью простого метода и 32-битной арифметики. Если развернуть, то и быстрее.