【问题标题】:Bitstream Optimizations比特流优化
【发布时间】:2014-11-03 18:54:15
【问题描述】:

我有一个从比特流中读取大量数据的程序。我这样做的方式并不高效,因为在进行性能测试时,大部分时间都花在了read 函数上。 这是我的阅读功能:

uint32_t bitstream::read(bitstream::size_type n) {
    uint32_t a = data[pos / 32];
    uint32_t b = data[(pos + n - 1) / 32];
    uint32_t shift = pos & 31;

    a >>= shift;
    b <<= 32 - shift;
    uint32_t mask = (uint32_t)(((uint64_t)1 << n) - 1);
    uint32_t ret = (a | b) & mask;

    pos += n;
    return ret;
}

如何进一步优化它?我的分析器说这个函数的大部分时间都花在计算 ret 上。

编辑:

关于内部,这就是我设置数据的方式:

bitstream::bitstream(const std::string &dat) : size( dat.size()*8 ) {
    // data has the type std::vector<uint32_t>
    data.resize((dat.size() + 3) / 4 + 1);
    memcpy(&data[0], dat.c_str(), dat.size());
}

【问题讨论】:

  • 您应该显示更多代码,bitstream 类内部的声明会很方便。
  • 您是否尝试过您的函数的任何变体并比较结果?你可以用这样的东西替换你的函数体:uint32_t ret = ((data[pos / 32] &gt;&gt; (pos &amp; 31)) | (data[(pos + n - 1) / 32] &lt;&lt; (32 - (pos &amp; 31)))) &amp; (static_cast&lt;uint32_t&gt;((static_cast&lt;uint64_t&gt;(1) &lt;&lt; n) - 1)); pos += n; return ret; .. 这是你的函数的微优化,只有ret temp 变量。您还可以比较编译器生成的程序集,看看它可能为您做什么。

标签: c++ bit-manipulation


【解决方案1】:

您是否总是读取相同数量的位,还是会有所不同?

如果你是,那么你可以尝试编写一个函数来只读取那么多位:n 是常量可能允许编译器进行一些更积极的优化。 (如果n 始终为 1,那么您可以编写一个更简单的读取方法)

【讨论】:

    【解决方案2】:

    答案主要取决于您使用的 CPU 架构和编译器,而不是语言。如果您的 CPU

    您可以在代码中以非常便宜的方式做的是使用预先计算的类 const 数组作为掩码,而不是在函数中每次都计算它。

    【讨论】:

    • 它将在标准英特尔处理器上运行,因此它可以是 32 位或 64 位。我最多读取 32 位,所以我什至可以打开它,谢谢你的提示。
    【解决方案3】:

    您可以尝试在 uint64_t 中保留一个 64 位的缓冲区,当它低于 32 位时立即读取另一个 32 位字。如果您经常读取远小于 32 位的大小,这可能会有所帮助。

    【讨论】:

      【解决方案4】:

      如果pos可以为0,那么shift也可以为0。结果b左移32位,有效地将其设置为0,a右移0也没有效果。您应该提前终止这种情况以避免无意义的操作。

      此外,您可以尝试使用掩码表来消除一次移位操作,您需要一个只有 32 个条目的 uint32_t 数组。

      大多数现代 Intel CPU 有两个 ALU 单元,要求它们连续执行 3 次 shfit,然后使用更多 ALU 运算来计算取决于这些移位结果的结果,这会限制您的吞吐量。

      最后,如果代码将在具有 BMI 功能的 CPU 上执行,您可以使用 BEXTR 指令或内部函数从位置 src 中提取 lenstart

      有关位操作指令的更多信息,请参阅http://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-10
        • 1970-01-01
        相关资源
        最近更新 更多