我需要为Cortex M0 CPU固件添加一些随机性。随机性并不重要,但是速度很重要。
我测试了网上发现的两个功能。使用random()
,我设法每31个时钟周期生成1个数字,而random_uint()
在20个周期中生成1个数字。我的目标是小于10。我还可以使用哪些其他功能?
unsigned random() {
unsigned b;
b = t1 ^ (t1 >> 2) ^ (t1 >> 6) ^ (t1 >> 7);
t1 = (t1 >> 1) | (~b << 31);
b = (t2 << 1) ^ (t2 << 2) ^ (t1 << 3) ^ (t2 << 4);
t2 = (t2 << 1) | (~b >> 31);
return t1 ^ t2;
}
unsigned random_uint() {
m_z = 36969 * (m_z & 65535) + (m_z >> 16);
m_w = 18000 * (m_w & 65535) + (m_w >> 16);
return (m_z << 16) + m_w;
}
答案 0 :(得分:2)
好吧,我相信它是32位架构,最快的可能是LCG RNG。使用来自数字食谱的值,周期为2 32
inline uint32_t random_u32(uint32_t prev) {
return prev*1664525U + 1013904223U; // assuming complement-2 integers and non-signaling overflow
}
int main() {
auto seed = 1U;
uint32_t = result;
result = seed = random_u32(seed);
result = seed = random_u32(seed);
result = seed = random_u32(seed);
...
return 0;
}
实际上,即使是更简单的版本,但周期更短,在C ++-11 minstd中使用的时间为2 31 -1。
inline uint32_t random_u32(uint32_t prev) {
return prev*48271U;
}
种子不得为0,以134775813U之类的奇数开头
答案 1 :(得分:1)
static unsigned int g_seed;
// Used to seed the generator.
inline void fast_srand(int seed) {
g_seed = seed;
}
// Compute a pseudorandom integer.
// Output value in range [0, 32767]
inline int fast_rand(void) {
g_seed = (214013*g_seed+2531011);
return (g_seed>>16)&0x7FFF;
}
答案 2 :(得分:1)
一些最快的生成器来自Xorshift发现的George Marsaglia系列,这是PRNG设计和PRNG测试的杰出贡献者。 Xorshift链接具有示例代码。给出的实现使用三个移位和三个XOR,这每个周期需要一个周期,而且很难被击败。