2015-08-28 2 views
0

Я написал код для моделирования системы связи. В этой системе связи есть часть, которую я запускаю параллельно с помощью pthreads. Он в основном исправляет ошибки, вызванные каналом.Как улучшить производительность времени кода C++ pthread, который использует барьеры

Когда я получаю фрейм битов, три компонента алгоритма работают над битами. Обычно они запускаются один за другим, что приводит к оптимальной производительности, но огромная задержка.

Идея состоит в том, чтобы заставить их работать параллельно. Но для достижения оптимальной производительности 3 компонента обрабатывают каждый бит одновременно.

Если я просто запускаю их параллельно, я получаю плохие результаты, но довольно быстрая производительность. Поэтому я использовал барьеры для синхронизации процесса, когда каждый бит обрабатывается тремя компонентами, прежде чем позволить им перейти к следующему бит.

Производительность этого метода является оптимальной. Но код работает очень медленно, я занимаю еще медленнее, чем серийная реализация.

Код работает на Ubuntu с компилятором GCC.

РЕДАКТИРОВАТЬ: Еще один вопрос, проделывают ли нитки, пока они ждут открытия барьера? и если да, то как я их помешаю?

+0

входной буфер должен быть доступен только для всех потоков, и каждый поток должен иметь выходной буфер для своих собственных. таким образом вам не понадобятся блокировки и могут обрабатываться параллельно. – SHR

+0

Это отличное решение, однако компоненты зависят друг от друга, они рекурсивны по своей природе. – user304584

+0

Как вы создаете темы? вы используете какой-то пул потоков? – SHR

ответ

2

Если вам буквально приходится синхронизировать после каждого бит, тогда довольно простая нить не будет подходящим подходом. Накладные расходы на синхронизацию будут намного превышать затраты на вычисления, поэтому вам будет лучше делать это в одном потоке.

Можете ли вы разделить работу на более высоком уровне? Например, весь кадр обрабатывается одним потоком, но параллельно обрабатывается несколько кадров?

+0

не обязательно должна быть побитовая синхронизация. Это дает мне возможность устанавливать барьеры на 25%, 50% и 75% длины блока. Спасибо за ваш ответ. Хотелось бы отметить, что я уже обрабатываю блоки параллельно, в реальном симуляции, но я выключаю его, когда анализирую свои результаты. – user304584

+0

Ahh, так что дело только в том, чтобы не допустить, чтобы одна нить зашла слишком далеко перед другими (или одна слишком сильно отстала). – caf

1

Это возможное решение, ИСПОЛЬЗУЯ НЕТ MUTEX.

Допустим, у вас есть 4 потока: основной поток, читающий некоторый вход, остальные 3 потока обрабатывают его кусок куском. поток может обрабатывать кусок сразу после того, как предыдущий обработал его.

поэтому у вас есть тип данных для фрагмента:

class chunk{ 
byte buffer[CHUNK_SIZE]; 
char status; // use char for atomic input, c++11 can use std::atomic_int. 
public: 
chunk():status(0); 
}; 

и у вас есть список кусков:

std::list<chunk> chunks; 

все нити, работающие на куски, пока они не достигают конца списка, но дождитесь, пока состояние достигнет состояния, статус основного потока будет равен 1 при выполнении входного блока. 1-й поток ждет, пока статус не будет равен 1, означает, что вход был выполнен и задано состояние 2, когда закончилось, поток 2 дождитесь, пока состояние равно 2, будет выполняться 1-й поток, а когда закончите обработку этого фрагмента, установите статус 3 и т. Д. наконец, основная нить подождать до состояния 4, чтобы получить результаты.

Важно при настройке статуса использовать = не ++, чтобы сделать его максимально возможным.

Смежные вопросы