С++: самый быстрый способ заполнения буфера случайными байтами

У меня есть этот большой массив char, который должен заполняться случайными байтами в высокой частоте. Интересно, существует ли какой-либо более быстрый способ, кроме наивного (для цикла - заполнение каждой ячейки случайным байтом) для этого. Нет требования к случайному качеству значений. Любой "случайный" мусор будет делать. Платформа - это окна

Ответы

Ответ 1

True random (только для Unix):

int fd = open("/dev/random", O_RDONLY);
read(fd, your_buffer, buffer_size);

Не полностью случайный (только для Unix):

int fd = open("/dev/urandom", O_RDONLY);
read(fd, your_buffer, buffer_size);

Постоянный случайный (если вы не используете srand(time(NULL)), переносимый):

for(size_t i = 0; i < buffer_size; i++)
    your_buffer[i] = rand() % 256;

Или что-то вроде:

memcpy(your_buffer, (void*)memcpy, buffer_size);

Ответ 2

Зависит от того, работаете ли вы в Linux или Windows, но в Linux должен работать memcpy из /dev/random.

В Windows вы можете использовать CryptGenRandom для заполнения буфера случайными данными: http://msdn.microsoft.com/en-us/library/aa379942.aspx. По-видимому, это эквивалент Windows для чтения данных из /dev/random. Python использует его для реализации своей функции OS.urandom в Windows: http://en.wikipedia.org/wiki/CryptGenRandom

Ответ 3

Возможно, вы могли бы сделать что-то вроде этого, если размер вашего буфера можно разделить на 4.

unsigned int v = rand(), *ptr = (unsigned int *)buf;
for(int i = 0; i < buffer_size / 4; i++)
    ptr[i] = (v << 16) ^ rand();

Просто идея;)

Ответ 4

Очень быстрый и простой способ генерации большого массива равномерно распределенных случайных чисел - использовать Mersenne twister. Если скорость критическая, это можно сделать даже с помощью SIMD.

Ответ 5

Это похоже на то, что вам нужно:

srandom(42);
memset(ptr, random(), len);

Создается только одно случайное число, но данные будут "случайными", чтобы вы могли обнаружить множество ошибок на основе неинициализированной памяти. Вы можете изменить семя и повторно запустить программу для тестирования с разными данными.

Если вам нужно это для отладки, вы также можете взглянуть на Valgrind.

Ответ 6

Настройте буфер с ненужными значениями. Если вам нужно снова заполнить массив char случайными байтами, то только части memcpy из мусорного буфера произвольно смещаются в массив char, пока он не будет полностью перезаписан. memcpy обычно очень быстро и оптимизирован для использования SIMD и инструкций кэша. Если вы скопируете сегменты достаточно большими, то накладные расходы на выбор случайных смещений, если они пренебрежимо малы - вы генерируете нежелательные данные со скоростью memcpy.

Ответ 7

Я написал библиотеку, которая создает "почти случайные" буферы: используя несколько буферов, заполненных псевдослучайными случайными данными, библиотека случайно выбирает буфер и возвращает его в приложение.

Эта библиотека была разработана в первую очередь настолько быстро, насколько это возможно, учитывая, что потребление памяти дешево и высокая пропускная способность.

Он может использоваться для обработки на основе блоков: полученные данные не являются случайными, но способ представления буферов в приложение, поэтому он генерирует случайный поток, который может быть достаточно большим, чтобы победить некоторый алгоритм сжатия.

Вы можете найти его по адресу: https://gitorious.org/randbuf/

Ответ 8

Поскольку этот вопрос помечен как windows/winapi, вы можете использовать CryptGenRandom.