С++: самый быстрый способ заполнения буфера случайными байтами
У меня есть этот большой массив 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.