I heard that HW random number generator is implemented in Intel’s CPU since IvyBridge architecture. Today I tried to use it.
How to use?
We can directly access rdrand instruction through assembler but it is easy to use intrinsics offered by the header immintrin.h. The header is same one as AVX intrinsics. For obtaining uniform double random number in the range of [0, 1], we can use the following simple code:
return (double)u / UINT64_MAX;
Speed test vs. Mersenne twister
This article says rdrand is capable of 7000M instructions / seconds. How fast is it? I compared the speed to MT(std::random implementation) in a simple experiment. Test code:
namespace ch = std::chrono;
std::uniform_int_distribution<unsigned int> dist;
const int Count = 1<<25;
unsigned int u;
for (int i = 0; i < Count; i++)
for (int i = 0; i < Count; i++)
auto start = ch::high_resolution_clock::now();
auto end = ch::high_resolution_clock::now();
double elapsed = (double)ch::duration_cast<ch::milliseconds>(end - start).count() / 1000.0;
std::cout << "MT : " << elapsed << " seconds" << std::endl;
start = ch::high_resolution_clock::now();
end = ch::high_resolution_clock::now();
elapsed = (double)ch::duration_cast<ch::milliseconds>(end - start).count() / 1000.0;
std::cout << "RdRand : " << elapsed << " seconds" << std::endl;
Execution time (executed in i7-3517U):
- MT : 0.421 seconds
- RdRand : 1.322 secods
I added simple modification to smallpt (simply replacing erand48 to the above rdrand function). The source is here. And comparison with MT version (note that erand48 is not used in Windows so I used std::random one instead). Source: MT version and rdrand version.
- MT : 89.107 seconds
- RdRand : 100.53 seconds
Seems no difference.
Microsoft Visual Studio 2012 introduces a native C++ unit testing tool. It is definitely good thing because we don’t have to write write c++/cli code merely for testings. Still, there is a case when we cannot use VS tools for compatibility reason; in order to make a software platform independent, we’d better to make its testings codes platform independent too. There are many platform independent unit testing frameworks for C++. Among them, I use googletest for this article.
Using googletest with VS2012
Download and build
- Download latest googletest (I downloaded gtest-1.6.0.zip)
- Unzip it and open \msvc\gtest.sln. It is VS2003 solution so it requires upgrade.
- Change number of variadic template parameters (in VS2012, 5 is the default value!). Add _VARIADIC_MAX=10 to PROJECT > Properties > Configuration Properties > C/C++ > Preprocessor > Preprocessor Definitions.
- Press F7 and build solution both for Debug and Release mode.
Create your project
- Add references to the built libraries to your project. For example, if the include files and built libraries are located on (your solution directory)\external\gtest-1.6.0\include and \lib. Add $(SolutionDir)external\gtest-1.6.0\include to VC++Directory > Include Directories and $(SolutionDir)external\gtest-1.6.0\lib to VC++Directory > Include Directories respectively, and add *.lib to Linker > Input.
- Add your test code, e.g.
Integrate googletest to VS2012 Test Explorer
- If you don’t see Test Explorer, click TEST > Windows > Test Explorer.
- Install googletest adapter plugin, and tests in your solution is automatically detected and listed in the Test Explorer window.
- Click Run All or run selected tests.
VS2012 code coverage tool with googletest
Without any settings, the code coverage tool detects internal code of googletest. The easiest way to avoid it is to wrap your code into a namespace (e.g. mynamespace::*), then tell the code coverage tool not to include the code outside the namespace.
- Create .runsettings file in your solution directory (use the template in this page).
- Add the following snippet to <Functions></Functions>.
- Click TEST > Test Settings > Select Test Settings File, and load your .runsettings file.