CHP*_*CHP 30 c random random-seed
我试图在计算集群中同时运行一段代码(2000个实例左右)的几个实例.它的工作方式是我提交作业,集群将在节点每隔一段时间打开时运行它们,每个节点有几个作业.对于使用时间种子的随机数生成中的大量实例,这似乎产生相同的值.
我可以使用一个简单的替代方案吗?重复性和安全性并不重要,快速生成独特的种子.什么是最简单的方法,如果可能的话,跨平台方法会很好.
Mys*_*ial 26
该rdtsc指令是一个非常可靠(和随机)的种子.
在Windows中,它可以通过__rdtsc()内在访问.
在GNU C中,可通过以下方式访问:
unsigned long long rdtsc(){
unsigned int lo,hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return ((unsigned long long)hi << 32) | lo;
}
Run Code Online (Sandbox Code Playgroud)
该指令测量自处理器通电以来的总伪周期.鉴于当今机器的频率很高,即使它们同时启动并且时钟速度相同,两个处理器也不太可能返回相同的值.
我假设您有一些流程启动其他流程.让它通过种子使用.然后,您可以让主进程只为每个进程传入一个随机数,以用作其种子.那种方式实际上只选择了一个任意种子......你可以用它来做时间.
如果您没有主进程启动其他进程,那么如果每个进程至少有一个唯一索引,那么您可以做的是让一个进程在内存中生成一系列随机数(如果共享内存)或在文件中(如果是共享磁盘)然后让每个进程将索引的随机数拉出来用作它们的种子.
没有什么能比单个种子的一系列随机数更均匀地分配种子.
PID和时间的组合应该足以获得唯一的种子.它不是100%跨平台,但getpid(3)在*nix平台和GetProcessIdWindows上将获得99.9%的平台.这样的事情应该有效:
srand((time(NULL) & 0xFFFF) | (getpid() << 16));
Run Code Online (Sandbox Code Playgroud)
您也可以从/dev/urandom*nix系统上读取数据,但是在Windows上没有相同的数据.
unsigned seed;
read(open("/dev/urandom", O_RDONLY), &seed, sizeof seed);
srand(seed); // IRL, check for errors, close the fd, etc...
Run Code Online (Sandbox Code Playgroud)
我还建议使用更好的随机数发生器.
如果可以使用 C++11 则考虑std::random_device. 我建议您观看链接以获取全面的指南。
从视频链接中提取基本信息:您永远不应该使用& ,而应该使用and - 在大多数情况下,以下内容就是您想要的:srandrandstd::random_devicestd::mt19937
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<int> dist(0,99);
for (int i = 0; i < 16; i++) {
std::cout << dist(mt) << " ";
}
std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)