cbhuang
10/2/2017 - 3:53 PM

A Brief Demo of C++11 <chrono> <random>

A Brief Demo of C++11

/** @file
 * @author  Chuan-Bin "Bill" Huang
 * @date    2013-06-27
 * @version 1.0
 *  
 * @brief   A Brief Demo of C++11 <chrono> and <random>
 * @section References
 * 
 * Original BBS posts:
 * 
 * <a href="https://www.ptt.cc/bbs/C_and_CPP/M.1372284252.A.99D.html">C++11 random</a> 
 * 
 * <a href="https://www.ptt.cc/bbs/C_and_CPP/M.1372283467.A.A74.html">C++11 chrono</a>
 * 
 */
 
 #include <iostream>
 #include <random>
 #include <chrono>
 using namespace std::chrono;
 // (wrong) using namespace std::random; 
  
 int main()
 {
     // Experimental Parameters
     size_t start_time = 0, end_time = 0, for_time = 0; // speed record
     unsigned int N = 1000000;
     double *a = new double [N]; // array of random numbers
     unsigned int i=0;
     std::normal_distribution<double> dist(0,1); // N(0,1) distribution
  
     // Format Conversion
     printf("1.Test duration_cast<precision>(duration_object).count() method:\n");
     size_t t64 = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     printf("  time now in dec ns: %u (uint64, directly obtained)\n", t64);
     printf("           in hex   : %16llx\n\n", t64);
  
     printf("2.make sure uint64 -> uint32 discards higher bits(suitable for seeding):\n");
     unsigned long t32 = static_cast<unsigned long>(t64);
     printf("  time now in hex ns: %16x (truncated to uint32)\n\n", t32);
  
     printf("3.generating %u N(0,1) random numbers using different engines...\n", N);
  
     // Time cost of for-loop body
     start_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     for(i=0; i<N; i++){}
     end_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     for_time = end_time - start_time;
     printf("%16u ns used on for-loop body\n", for_time);
  
     // mt19937 engine
     start_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     std::mt19937 mt(static_cast<unsigned long>(duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count()));
     for(i=0; i<N; i++)
         a[i] = dist(mt);
     end_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     printf("%16u ns for mt19937\n", (end_time-start_time-for_time));
  
     // mt19937_64 engine
     start_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     std::mt19937_64 mt64(static_cast<unsigned long>(duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count()));
     for(i=0; i<N; i++)
         a[i] = dist(mt64);
     end_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     printf("%16u ns for mt19937_64\n", (end_time-start_time-for_time));
  
     // minstd_rand engine
     start_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     std::minstd_rand  min_rnd(static_cast<unsigned long>(duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count()));
     for(i=0; i<N; i++)
         a[i] = dist(min_rnd);
     end_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     printf("%16u ns for minstd_rand\n", (end_time-start_time-for_time));
  
     // default_random_engine
     start_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     std::default_random_engine def_rnd(static_cast<unsigned long>(duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count()));
     for(i=0; i<N; i++)
         a[i] = dist(def_rnd);
     end_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     printf("%16u ns for default_random_engine\n", (end_time-start_time-for_time));
  
     // random_device (hardware generator)
     start_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     std::random_device rd;
     for(i=0; i<N; i++)
         a[i] = dist(rd);
     end_time = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()).count();
     printf("%16u ns for random_device\n", (end_time-start_time-for_time));
  
     delete [] a;
     printf("\nProgram Ended! Press Enter to quit.");
     std::cin.get();
     return 0;
 }