掩码中的均匀随机位

时间:2018-11-29 13:20:38

标签: random rust statistics bit-manipulation

假设我有一个64位无符号整数(u64)tasks,并且设置了一个或多个位。

我想从project.tasks.getByName("tasks").doFirst { println "do something before task [tasks] executes" } 中随机选择一个设置位,以给出一个新的掩码mask,以便m设置一个位。一些伪代码可以做到这一点:

x

但是,我需要尽可能快地执行此操作(与上述类似的低级语言代码正在减慢热循环的速度)。有人有更有效的方案吗?

1 个答案:

答案 0 :(得分:4)

如何对此进行优化的细节取决于您未指定的几个因素-目标体系结构,掩码中设置位的预期数量,要使用的语言,对随机性的要求等等。在不知道更多细节的情况下,很难给出有用的答案,但是我会给出一些可能仍然有用的提示。

大多数现代体系结构都有一条指令,用于对整数(通常称为“ popcount”)中设置的位数进行计数,并且该指令以大多数低级语言公开。在Rust中,您可以使用count_ones() method。这样一来,您就可以从k位的总数中进行选择。

然后,您可以在i0(含)之间生成一个随机数k - 1。下一步是选择i中的第mask位。一个有效的方法是以下循环(Rust代码):

for _ in 0..i {
    mask &= mask - 1;
}
let new_mask = 1 << mask.trailing_zeros();

循环将在每次迭代中清除最低有效位。自i < k起,我们知道循环后mask不能为零。最后一行从仍设置的mask的最低有效位生成新的掩码。

在常见的体系结构上,瓶颈可能是随机数生成器。如果您使用的是Rust的rand板条箱,则可以使用SmallRng来提高性能,但要以加密不安全为代价,这可能与您的用例无关。