Мне нужно оптимизировать некоторый унаследованный код и довольно новичок в C++.Контейнер C++ для высокой производительности FIFO
Код выполняет сетевую обработку пакетов в двух потоках, один поток передает пакеты в FIFO [topupBuffer
], а другой поток считывает из очереди и отправляет их через IP-порт [writeToIPOutput
]. Унаследованный код использует std :: deque для реализации FIFO.
Однако при запуске программы используется много CPU, до 50% (там, где это должно быть больше похоже на 5%). Похоже, что запуск gprof обнаруживает, что виновником является std::deque
. (Я не уверен, что я правильно интерпретировать результаты профиля, поэтому помощь приветствуется)
Excepts с выхода профиля: 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
тратит слишком много времени на назначение. Я могу поработать над этим. Но topupBuffer
тратит время в std::deque
.
Это правильная интерпретация выхода профиля?
Если это так, то используется другой контейнер, который будет более эффективным, и если да, то какой?
Спасибо
EDIT I пояснительные примечания в конце дерева вызовов говорит:
% 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 тратится на различные методы deque (push_back, размер и т. Д.). Правильно? Таким образом, 0,71 составляет более половины общего времени (1,15), потраченного на детей (??)
Вы пытались использовать нашего любимого друга, ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector)? Для FIFO, хотя и обыденный, но вы можете рассмотреть ['std :: queue'] (http://en.cppreference.com/w/cpp/container/queue) с вектором в качестве базового контейнера – WhiZTiM
Интересно, ['boost :: lockfree :: queue'] (http://www.boost.org/doc/libs/1_59_0/doc/html/boost/lockfree/queue.html) будет работать лучше. – NathanOliver
Попробуйте сделать каждый элемент в 'deque' коротким вектором рабочих элементов, таким образом, у вас не будет столько операций над общей структурой данных. –