在C++中创建统一的随机数的最快方法是什么?

问题描述:

我需要在for循环中生成统一的随机数。 for循环用于1000000个数字。还有另一个for循环,它在2000里面。所以我生成了2 * 10^9的统一随机数。我用下面的方法:在C++中创建统一的随机数的最快方法是什么?

#include <random> 
    double zeta; 
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); 
     auto uniform_rand = bind(uniform_real_distribution<double>(0,1), mt19937(seed)); 
    for(int j=0; j<1000000; j++) 
       for(int i=0; i<2000; i++) 
     zeta=-eta/2.0+uniform_rand()*eta; // in the range (-eta/2, +eta/2) 
theta[i]+=zeta; 
    end 
end 
+4

'std :: bind'往往被lambdas取代,无论是在可读性和性能方面。 – chris

+4

这是一个非常多的随机数字。如果你需要这么多,为什么不把它分解成线程来利用多核? – tadman

+0

对不起,我不明白你是什么意思@tadman –

它几乎与你的一样。我只是没有看到任何需要一个活页夹或lambda。

编辑:我也将发生器从mt19937更改为minstd_rand,这使得代码快了88倍。使用mt19937代码的性能与问题中的代码大致相同。

#include <random> 

int main() { 
    /*std::mt19937 gen(std::random_device{}());*/ 
    // Changing mt19937 to minstd_rand makes the code run 88 times faster! 
    std::minstd_rand gen(std::random_device{}()); 
    std::uniform_real_distribution<double> dist(0, 1); 
    for(unsigned int i = 0; i < 1000000; ++i) { 
     for(unsigned int j = 0; j < 2000; ++j) { 
      double anotherRandomNumber = dist(gen); 
      // Do whatever you want with generated random number. 
     } 
    } 
} 
+0

它比我写的真的快吗? –

+0

它是否在不同的运行中创建不同的随机数字? –

+0

@OliverRange是的,它每次使用'std :: random_device'来播放随机生成器。但有时它不会工作,请参阅https://*.com/questions/18880654/why-do-i-get-the-same-sequence-for-every-run-with-stdrandom-device-with-mingw –

使用这种算法从here

uint64_t s[2] = { 0x41, 0x29837592 }; 

static inline uint64_t rotl(const uint64_t x, int k) { 
    return (x << k) | (x >> (64 - k)); 
} 

uint64_t next(void) { 
    const uint64_t s0 = s[0]; 
    uint64_t s1 = s[1]; 
    const uint64_t result = s0 + s1; 

    s1 ^= s0; 
    s[0] = rotl(s0, 55)^s1^(s1 << 14); // a, b 
    s[1] = rotl(s1, 36); // c 

    return result; 
} 

double uniform() { 
    return next()*(1.0/18446744073709551616.0); 
} 

这比我的机器上的例子更快4倍

注意:您需要种子s,或许与std::random_device

+0

能否请您提供一个用于循环的答案,就像我的情况一样? –

+0

@OliverRange:将这段代码粘贴到你的代码中,用'uniform()'替换'uniform_rand()'。 – geza

+0

我不知道在哪里发布它。主要和之前的循环后? –