Ich muss einige Legacy-Code optimieren und bin ziemlich neu in C++.C++ Container für Hochleistungs-FIFO
Der Code verarbeitet Netzwerkpakete in zwei Threads, wobei ein Thread Pakete zu einem FIFO [topupBuffer
] und der andere Thread aus der Warteschlange liest und ihnen einen IP-Socket [writeToIPOutput
] sendet. Der Legacy-Code verwendet std :: deque, um den FIFO zu implementieren.
Allerdings läuft das Programm eine Menge CPU, bis zu 50% (wo es mehr wie 5% sein muss). Laufen gprof scheint zu offenbaren std::deque
ist der Schuldige. (Ich bin nicht sicher, ob ich das Profil Ergebnisse richtig bin zu interpretieren, so Hilfe ist willkommen)
excepts aus dem Profilausgang: topupBuffer Hierarchie:
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]
und
[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 Hierarchie
[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]
Ich denke, writeToIPOutput
verbringt zu viel Zeit bei der Zuweisung. Daran kann ich arbeiten. Aber topupBuffer
verbringt seine Zeit in std::deque
.
Ist das die korrekte Interpretation der Profilausgabe?
Wenn ja, dann wird ein anderer Container effizienter und wenn ja, welcher?
Danke
EDIT I die Erläuterungen am Ende der Aufrufstruktur sagt:
% 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.
So bei bufferizeTsPackets
suchen, 1,15 in ihren Kindern verbracht wird, davon 0,30, + 0.30 + 0.11 = 0.71 wird in verschiedenen Deque-Methoden (push_back, size etc.) ausgegeben. Recht? Also 0,71 ist mehr als die Hälfte der Gesamtzeit (1,15) verbrachte in den Kindern (??)
Haben Sie versucht, unseren geliebten Freund, ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector) zu verwenden? Für FIFO, obwohl banal, aber Sie möchten vielleicht prüfen, ['std :: queue'] (http://en.cppreference.com/w/cpp/container/queue) mit einem Vektor als zugrunde liegenden Container – WhiZTiM
Ich frage mich, ob Eine ['boost :: lockfree :: queue'] (http://www.boost.org/doc/libs/1_59_0/doc/html/boost/lockfree/queue.html) würde besser funktionieren. – NathanOliver
Versuchen Sie, jedes Element in der 'Deque' zu einem kurzen Vektor von Arbeitselementen zu machen. Auf diese Weise haben Sie nicht so viele Operationen auf der gemeinsamen Datenstruktur. –