我遇到了一个我不理解的性能问题。我正在研究的系统有两个看起来像这样的线程:
版本A:
其中'Selection'使数据变细,而线程1末尾的FIFO是线程2开头的FIFO(FIFO实际上是TBB并发队列)。出于性能原因,我将线程更改为如下所示:
版本B:
最初,这种优化证明是成功的。线程1能够实现更高的吞吐量。我对Thread 2的性能看起来并不太认真,因为我预计CPU使用率会更高,并且(由于数据变薄)这不是主要问题。但是,我的一位同事要求对版本A和版本B进行性能比较。为了测试设置我有线程2的套接字(一个boost asio tcp套接字)写入同一个框(127.0.0.1)上的iperf实例显示最大吞吐量的目标。
为了比较这两个设置我首先尝试强制系统以500 Mbps的速率从套接字写出数据。作为性能测试的一部分,我监控了顶部。我看到的让我感到惊讶。版本A没有出现在'top -H'上,也没有出现在iperf上(这实际上是被怀疑的)。然而,版本B(我的'增强版')出现在'top -H'上,cpu利用率约为10%,而且(奇怪的是)iperf出现了8%。
显然,这对我来说意味着我做错了什么。我似乎无法证明我的确如此!我已经确认的事情:
我唯一能想到的是我在套接字写入中引入了一个更紧密的循环。但是,在500 Mbps时,我不希望我的进程和 iperf上的cpu使用量会增加吗?
我不知道为什么会这样。我的同事和我基本上没有想法。有什么想法或建议吗?我很乐意在这一点上尝试任何事情。
答案 0 :(得分:0)
如果没有代码片段或实际数据量,这将很难分析。
有一件事是我想到的:如果预格式化的数据流明显大于后格式化,那么您可能会花费更多的带宽/周期来通过FIFO(套接字)边界复制更多数据。
尝试估算或测量每个阶段的数据速率。如果“选择”输出的数据速率较高,请考虑将格式移动到边界另一侧的效果。配置A中的select->格式转换是否可能不需要复制,配置B是否需要大量复制?
......只是在没有更深入了解系统的猜测中。
答案 1 :(得分:0)
如果FIFO是版本A中的瓶颈怎么办。那么两个线程都会在大多数时间内等待FIFO。在版本B中,您将更快地将数据移交给iperf
。
答案 2 :(得分:0)
您在FIFO队列中存储的确切内容是什么?你存储数据包,即缓冲区吗?
在版本A中,您将格式化数据(可能是字节)写入队列。因此,在套接字上发送它只需写出一个固定大小的缓冲区。
但是在版本B中,您将高级数据存储在队列中。格式化它现在创建更大的缓冲区大小,直接写入套接字。这导致TCp / ip堆栈在分段和处理中花费CPU周期。开销...
这是我的理论基于你到目前为止所说的内容。