【问题标题】:c++: Fastest way to fill a buffer with random bytesc++:用随机字节填充缓冲区的最快方法
【发布时间】:2011-09-15 08:19:26
【问题描述】:

我有一个大字符数组,需要用高频随机字节填充。我想知道除了天真的方式(使用 for 循环 - 用随机字节填充每个单元格)之外是否有更快的方式来做到这一点。对值的随机质量没有要求。任何“随机”的垃圾都可以。平台是windows

【问题讨论】:

  • 这个有什么用,因为有了这些信息,很难给出合适的解决方案。
  • 只需要模拟一个未初始化的内存区域,里面有垃圾
  • xkcd.com/221 只是 memset 任意值。
  • 如果对随机质量没有要求,memset(ptr, 0, len) 会用random number 填满缓冲区。

标签: c++ windows winapi


【解决方案1】:

真正的随机(仅限 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);

【讨论】:

  • memcpy(your_buffer, (void*)memcpy, buffer_size); 对于大缓冲区可能会失败。 % 256 也是多余的
【解决方案2】:

取决于您使用的是 Linux 还是 Windows,但在 Linux 上从 /dev/random 执行 memcpy 应该可以工作。

在 Windows 上,您可以使用 CryptGenRandom 用随机数据填充缓冲区:http://msdn.microsoft.com/en-us/library/aa379942.aspx。 显然,这相当于从 /dev/random 读取数据的 Windows。 Python 使用它在 Windows 上实现其OS.urandom 函数: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】:

      设置一个带有垃圾值的缓冲区。如果您需要再次用随机字节填充 char 数组,则只需 memcpy 从垃圾缓冲区中随机偏移到 char 数组的部分,直到它被完全覆盖。 memcpy 通常非常快并且经过优化以利用 SIMD 和缓存指令。如果您复制的段足够大,那么选择随机偏移量的开销可以忽略不计 - 您正在以 memcpy 的速度生成垃圾数据。

      【讨论】:

        【解决方案6】:

        由于这个问题被标记为 windows/winapi,你可以使用CryptGenRandom

        【讨论】:

          【解决方案7】:

          我编写了一个库,可以产生“几乎随机”的缓冲区:使用多个填充了伪随机随机数据的缓冲区,库随机选择一个缓冲区并将其返回给应用程序。

          考虑到内存消耗便宜且带宽高,这个库首先被设计为尽可能快。

          它可用于基于块的处理:产生的数据并不是真正随机的,但缓冲区呈现给应用程序的方式是随机的,因此它会生成一个随机流,该流可以大到足以击败某些压缩算法。

          您可以在以下位置找到它:https://gitorious.org/randbuf/

          【讨论】:

          • 从多个缓冲区中挑选有什么好处,还是只是为了新颖和浪费内存;)?
          • @IsaacWoods 因为否则相同的数据将无休止地写入用户的缓冲区。通过使用随机选择的多个源缓冲区,它会降低数据流的可预测性。
          【解决方案8】:

          这似乎可以满足您的需要:

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

          仅生成一个随机数,但数据将是“随机”的,足以让您发现许多基于未初始化内存的错误。您可以更改种子并重新运行程序以使用不同的数据进行测试。

          如果您需要它进行调试,您可能还想看看Valgrind

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-11-18
            • 2019-07-31
            • 1970-01-01
            • 2023-03-25
            • 1970-01-01
            • 2018-02-07
            • 1970-01-01
            相关资源
            最近更新 更多