gpt4 book ai didi

c++ - 更快的位读取?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:17 25 4
gpt4 key购买 nike

在我的应用程序中,20% 的 CPU 时间花在了通过位读取器读取位(skip)上。有谁知道如何使以下代码更快?在任何给定时间,我不需要超过 20 个有效位(这就是为什么我在某些情况下可以使用 fast_skip)。

位以大端顺序读取,这就是需要字节交换的原因。

class bit_reader
{
std::uint32_t* m_data;
std::size_t m_pos;
std::uint64_t m_block;

public:
bit_reader(void* data)
: m_data(reinterpret_cast<std::uint32_t*>(data))
, m_pos(0)
, m_block(_byteswap_uint64(*reinterpret_cast<std::uint64_t*>(data)))
{
}

std::uint64_t value(std::size_t n_bits = 64)
{
assert(m_pos + n_bits < 64);

return (m_block << m_pos) >> (64 - n_bits);
}

void skip(std::size_t n_bits) // 20% cpu time
{
assert(m_pos + n_bits < 42);

m_pos += n_bits;

if(m_pos > 31)
{
m_block = _byteswap_uint64(reinterpret_cast<std::uint64_t*>(++m_data)[0]);
m_pos -= 32;
}
}

void fast_skip(std::size_t n_bits)
{
assert(m_pos + n_bits < 42);
m_pos += n_bits;
}
};

目标硬件是 x64。

最佳答案

我从之前的评论中看到您正在以 JPEG 格式解压缩霍夫曼/算术编码流。

  • skip()value() 非常简单,可以内联。编译器有可能将移位寄存器和缓冲区指针一直保留在寄存器中。使用 restrict 修饰符在此处和调用方中创建所有指针可能有助于告诉编译器您不会将霍夫曼解码的结果写入位缓冲区,从而允许进一步优化。<
  • 每个霍夫曼/艺术符号的平均长度都很短 - 因此,8 次中有 7 次不需要填充 64 位移位寄存器。研究为编译器提供分支预测提示。
  • JPEG 位流中的任何符号都不会超过 32 位。这是否允许进一步优化?
  • skip() 是一条繁重的路径的一个非常合乎逻辑的原因是您将其称为很多。您是一次消耗整个符号而不是这里的每一位,不是吗?您可以通过计算符号和表格查找中的前导 0 或 1 来执行一些巧妙的技巧。
  • 您可以考虑安排移位寄存器,使流中的下一位是 LSB。这将避免 value()
  • 中的偏移

关于c++ - 更快的位读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11854438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com