C++ 将uint64\u t rdtsc值转换为uint32\u t

C++ 将uint64\u t rdtsc值转换为uint32\u t,c++,random,integer,unsigned-integer,rdtsc,C++,Random,Integer,Unsigned Integer,Rdtsc,我有一个RNG函数xorshift128plus,它接受一个Xorshift128PlusKey: /** * \brief Keys for scalar xorshift128. Must be non-zero. * These are modified by xorshift128plus. */ struct Xorshift128PlusKey { uint64_t s1;

我有一个RNG函数xorshift128plus,它接受一个Xorshift128PlusKey

/** 
        * \brief Keys for scalar xorshift128. Must be non-zero.
        * These are modified by xorshift128plus.
        */
        struct Xorshift128PlusKey
        {
            uint64_t s1;
            uint64_t s2;
        };

        /** 
        * \brief Return a new 64-bit random number.
        */
        uint64_t xorshift128plus(Xorshift128PlusKey* key);
我想使用rdtsc(处理器时间戳)为我的RNG设定种子。问题是msvc下的
\uu rdtsc
内在函数返回一个64位无符号整数,种子必须是32位无符号整数。在保持随机性的同时,将rdtsc转换为种子的最佳方法是什么。转换必须尽可能快


我不能使用标准库增强。(用于游戏引擎)

64位处理器时间戳根本不是随机的,因此在将其缩小到32位时不需要保留随机性。您可以简单地使用最低有效32位作为种子。随机性是PRNG的责任,而不是种子的责任

unsigned __int64 tsc = __rdtsc();
uint32_t seed = static_cast<uint32_t>(tsc & 0xFFFFFFFF);
unsigned u int64 tsc=u rdtsc();
uint32\u t seed=静态强制转换(tsc&0xFFFFFFFF);

64位处理器时间戳根本不是随机的,因此在将其缩小到32位时不需要保留随机性。您可以简单地使用最低有效32位作为种子。随机性是PRNG的责任,而不是种子的责任

unsigned __int64 tsc = __rdtsc();
uint32_t seed = static_cast<uint32_t>(tsc & 0xFFFFFFFF);
unsigned u int64 tsc=u rdtsc();
uint32\u t seed=静态强制转换(tsc&0xFFFFFFFF);

我认为“保持随机性”是相对的;您将丢失一半的信息。您希望在可以保留的时间戳中发现什么随机性?唯一模糊随机的是机器最后一次启动的时间(可能根本不是随机的,例如,如果你的程序在启动时自动运行)。既然低32位的变化要比高32位的变化快得多,为什么不直接采用低32位呢?我想“保持随机性”是相对的;您将丢失一半的信息。您希望在可以保留的时间戳中发现什么随机性?唯一模糊随机的是机器最后一次启动的时间(可能根本不是随机的,例如,如果你的程序在启动时自动运行)。既然低32位的变化要比高32位的变化快得多,为什么不直接采用低32位呢?谢谢你的回答!或者写入
uint32\u t seed=\u\u rdtsc()并让编译器扔掉高位。(如果你真的想学究的话,你可能必须先将其强制转换或分配给
uint64\t
,这样在收窄时你会得到无符号溢出,而不是有符号溢出。但是强制转换和安定似乎毫无意义。)@PeterCordes谢谢,这里发布的代码是按照图示/教育目的编写的。这相当于您的建议,优化编译器很可能会生成相同的指令。您可能还需要强制转换以避免编译器警告。是的,编译器知道如何优化这些指令,事实上,他们也知道如何优化这些指令。(). 没错,如果启用
-Wall
,MSVC会发出警告,但MSVC自己的头文件会发出带有
-Wall
的警告。gcc/clang/icc即使使用
-Wall-Wextra-Wpedantic
也不会发出警告。我通常不使用MSVC,所以我只习惯于gcc/clang
-Wall
警告。我仍然认为,
&0xFFFFFFFF
的可读性较差,因为您必须计算数字,以确保有8个或更多数字,因此它实际上是禁止操作的。忽略它不会导致警告。谢谢您的回答!或者写入
uint32\u t seed=\u\u rdtsc()并让编译器扔掉高位。(如果你真的想学究的话,你可能必须先将其强制转换或分配给
uint64\t
,这样在收窄时你会得到无符号溢出,而不是有符号溢出。但是强制转换和安定似乎毫无意义。)@PeterCordes谢谢,这里发布的代码是按照图示/教育目的编写的。这相当于您的建议,优化编译器很可能会生成相同的指令。您可能还需要强制转换以避免编译器警告。是的,编译器知道如何优化这些指令,事实上,他们也知道如何优化这些指令。(). 没错,如果启用
-Wall
,MSVC会发出警告,但MSVC自己的头文件会发出带有
-Wall
的警告。gcc/clang/icc即使使用
-Wall-Wextra-Wpedantic
也不会发出警告。我通常不使用MSVC,所以我只习惯于gcc/clang
-Wall
警告。我仍然认为
&0xFFFFFFFF
的可读性较差,因为您必须计算数字以确保有8个或更多数字,因此实际上是禁止操作。忽略它不会导致警告。