【问题标题】:Counting set values in std::vector<bool>计算 std::vector<bool> 中的设置值
【发布时间】:2019-12-10 02:24:39
【问题描述】:

std::vector&lt;bool&gt; 是否使用POPCNT 指令来计算std::count 算法的结果?

如果不是,是否可以在不复制粘贴完整向量的情况下实现?为此,我需要访问实际存储在该向量中的 unsigned int 值,这可能吗?

如果重要的话,我只需要 VC++ 2017 解决方案。

【问题讨论】:

  • 您可以轻松检查生成的程序集以了解它的作用。你试过吗?
  • @NathanOliver 刚刚检查过。正如我所料,它没有。有没有简单的方法可以做到这一点?
  • @NathanOliver 循环中的按位移位比 POPCNT 慢一个数量级:POPCNT 需要 1 个周期来处理 32 个布尔值。
  • 我不确定用矢量执行此操作的方法,因为您没有任何直接访问权限或任何布局保证。也就是说,boost::dynamic_bitset 有一个 count 函数,可以优化使用 POPCNT
  • 如果你知道编译时的位数,你也可以使用std::bitset,它还有一个可以利用POPCNT的计数函数

标签: c++ visual-c++ vector boolean


【解决方案1】:

不幸的是,std::count 不使用popcnt 代替std::vector&lt;bool&gt;(至少对于 GNU C++ 标准库)。

std::vector&lt;bool&gt; 也不提供对其原始存储的访问,std::vector&lt;bool&gt;::data 返回void

另一种解决方案是使用boost::dynamic_bitset&lt;&gt;boost::dynamic_bitset&lt;&gt;::count 使用 popcnt 指令,参见 assembly output

GNU C++ std::vector&lt;bool&gt; 实现次优,其大小为 40 字节。而sizeof(boost::dynamic_bitset&lt;&gt;) 是 32。

【讨论】:

  • 不是我想听到的,但感谢您的快速回复。我不喜欢boost,我想我会包装std::vector&lt;uint64_t&gt;..
  • @Sonts 有道理,sizeof(std::vector&lt;uint64_t&gt;) 是 24,甚至比boost::dynamic_bitset&lt;&gt; 还要好。除非您需要来自位字符串的boost::dynamic_bitset&lt;&gt; 构造函数。
  • 我要强调的是,正确配置编译器比使用特定的模板解决方案更重要。
  • @MarekR 编译器不够聪明,无法自行生成快速代码,无论您如何配置它们。获得最佳性能的唯一方法是回退到较低的水平,在我的例子中是__popcnt64 intrinsic。
  • @MarekR 这样的优化技巧是不可靠的。即使使用/arch:AVX2,VC++ 还是在循环中将该代码编译为BLSR
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 2016-11-12
相关资源
最近更新 更多