gpt4 book ai didi

用于高性能 FIFO 的 C++ 容器

转载 作者:太空狗 更新时间:2023-10-29 22:58:29 25 4
gpt4 key购买 nike

我需要优化一些遗留代码,而且我对 C++ 还很陌生。

代码在两个线程中进行网络数据包处理,一个线程将数据包推送到 FIFO [topupBuffer],另一个线程从队列中读取并将它们发送到 IP 套接字 [writeToIPOutput ]。遗留代码使用 std::deque 来实现 FIFO。

但是,运行该程序会占用大量 CPU,高达 50%(需要更接近 5%)。运行 gprof 似乎揭示了 std::deque 是罪魁祸首。 (我不确定我是否正确解释了配置文件结果,因此不胜感激)

除了配置文件输出:topupBuffer 层次结构:

index % time    self  children    called     name
0.65 2.51 1/1 DvIPFilePlayback::topupBufferThreadMethod(void*) [2]
[1] 60.5 0.65 2.51 1 DvIPFilePlayback::topupBuffer() [1]
0.27 1.15 4025575/4025575 DvIPPlaybackBC::bufferizeTsPackets(TPlaybackBuffer&, int&, int&) [5]
0.03 0.56 4026668/4026668 std::deque<TTsPacket, std::allocator<TTsPacket> >::push_back(TTsPacket const&) [6]
0.03 0.15 4046539/5749754 std::deque<TPlaybackBuffer, std::allocator<TPlaybackBuffer> >::size() const [17]

[5]     27.2    0.27    1.15 4025575         DvIPPlaybackBC::bufferizeTsPackets(TPlaybackBuffer&, int&, int&) [5]
0.04 0.30 4031674/4031674 std::deque<TTsPacket, std::allocator<TTsPacket> >::pop_front() [11]
0.03 0.30 8058004/8058004 std::deque<TTsPacket, std::allocator<TTsPacket> >::size() const [12]
0.01 0.19 576183/576183 DvPlaybackBC::insertToPlaybackBuffer(TPlaybackBuffer const&) [22]
0.04 0.11 4029401/4029401 std::deque<TTsPacket, std::allocator<TTsPacket> >::front() [25]

writeToIPOutput 层次结构

[3]     36.8    0.92    1.00       1         DvIPPlaybackBC::writeToIPOutput() [3]
0.31 0.00 1129444/1129444 TPlaybackBuffer::operator=(TPlaybackBuffer const&) [13]
0.01 0.18 579235/1155128 std::deque<TPlaybackBuffer, std::allocator<TPlaybackBuffer> >::push_back(TPlaybackBuffer const&) [8]
0.03 0.10 1135318/1135318 std::deque<TPlaybackBuffer, std::allocator<TPlaybackBuffer> >::pop_front() [27]

我猜 writeToIPOutput 在赋值上花费了太多时间。我可以解决这个问题。但是 topupBufferstd::deque 中花费了时间。

这是配置文件输出的正确解释吗?

如果是这样,那么使用不同的容器是否会更有效?如果是这样,使用哪个容器?<​​/p>

谢谢

编辑我调用树末尾的注释说:

% time  This is the percentage of the `total' time that was spent
in this function and its children. Note that due to
different viewpoints, functions excluded by options, etc,
these numbers will NOT add up to 100%.

self This is the total amount of time spent in this function.

children This is the total amount of time propagated into this
function by its children.

所以看看 bufferizeTsPackets,1.15 花在了它的子节点上,其中 0.30 + 0.30 + 0.11 = 0.71 花在了不同的双端队列方法(push_back、size 等)上。正确的?所以 0.71 超过了花在 child 身上的总时间 (1.15) 的一半 (??)

最佳答案

更有效的结构是使用数组实现循环队列(环形缓冲区)。

由于数组是固定大小的,您要么必须使数组足够大,以免数据溢出;要么或者只存储最后 N 个值,其中 N 是缓冲区的容量。

许多嵌入式系统使用数组来减少由动态内存位置引起的内存碎片问题。

如果你的数组足够小,它可以放入处理器的数据缓存中;这加快了计算速度。

关于用于高性能 FIFO 的 C++ 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40345111/

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