![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| VictorTsaregorodtsev |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 274 Регистрация: 28.7.2006 Репутация: 1 Всего: 8 |
Я бы всё-таки Продюсера сделал одним потоком - дал ему немного повыше приоритет, и пусть он в вечном цикле крутит цикл проверки поступления новых данных от всех устройств. Проверил все устойства - sleep(0) и обратно к началу вечного цикла. Думаю, уведомления от устройства у Вас идут в виде изменения значения указателя в кольцевом буфере - поэтому разные скорости поступления данных от разных устройств одним потоком обработать будет можно (поток на каждое устройство сохраняет значение проверенной позиции в кольцевом буфере, на следующей итерации сравнивает старое значение с текущим, и если есть расхождения - копирует кусок свежих данных в буфер соответствующего обрабатывающего потока). Обрабатывающему потоку же дал 2 буфера - когда заполнился один - поток начинает его обрабатывать (а принимающий данные поток с этого момента начинает класть данные из кольцевого буфера во второй рабочий буфер обрабатывающего потока). Обработал обрабатывающий поток буфер - ждёт, когда принимающий поток заполнит второй рабочий буфер, чтобы его забрать себе и взамен дать обрабатывающему потоку указатель на первый буфер для складывания туда данных. Т.е. раз буфера 2 - можно снизить риск, что обрабатывающий поток протормозит и его единственный буфер начнёт перезаписываться Продюсером. Ну и всю эту часть (синхронизация потоков и передача данных между ними) делал бы "вручную" без всяких лишних библиотек классов. При этом будет возможен ещё один вариант ускорения - если буферы данных выровнять на границы параграфов, то можно будет копировать по 8 или по 16 байт одной командой (с использованием ММХ или SSE). Но надо будет или функцию копирования написать свою (вместо стандартной memcpy или виндовозовской CopyMemory), или взять оптимизированную под современные процессоры функцию копирования данных (у Агнера Фога была библиотечка на такую тему), или прописать копирование данных на чистом С (а там уж пусть компилятор старается-оптимизирует этот участок кода). Т.е. если будет идти большая нагрузка на проц при "отключенной" реальной обработке данных Ресиверами - то может быть копирование данных от Продюсера к Ресиверу тормозит (библиотеки классов - такие библиотеки...). |
|||
|
||||
| borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
не совсем. я получаю прерывание от устройства каждую 1/10-ю от длины буфера. поток Продюсера "висит" на событии от драйвера (WaitForSingleObject - в user-space, SetEvent - в kernel), и делать бесконечный цикл (кушающий процессор) мне нет необходимости, а sleep(0) в Windows (проверено!) может кушать практически сколько угодно времени :(
Эти "качели" у меня получаются "нахаляву" из-за того, что драйвер выдаёт сообщение о заполнении буфера, причём у меня получается не два буфера, как Вы предлагаете, а 10. И ещё: IMHO в моём варианте лоченье происходит на меньшее время, т.к. лочится только код копирующий указатели, а не массивы Добавлено через 2 минуты и 51 секунду Тогда мне придётся лочить этот входной массив на время копирования в него, а сейчас у меня лочится только копирование указателей... аууууу -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Если вам очень критична скорость, то имеет смысл вообще отказаться от stl контейнеров (в этом месте)
Нужно сделать контейнер в котором можно разделить процессы выделения места (на это время контейнер будет лочится) и перенесение информации в это выделенное место (на это время контейнер лочить не надо) Это должна быть несколько модифицированная queue, с методами:
При такой организации вообще не надо копировать данные между очередями. Следующей точкой оптимизации может стать отказ от копирования памяти вообще - сделать в драйвере пул памяти и отмэпировать его в пользовательское пространство. Драйвер будет общаться с клиентом пересылая ему указатели, смотрящие в этот пул |
|||
|
||||
| borisbn |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 22 Всего: 135 |
Во-первых память ядра уже отмапирована в пользовательское пространство, так что данные не копируются из драйвера Во-вторых данные для 8-ми каналов мультиплексированы в один буфер и их всё равно нужно разбирать на разные массивы В-третьих, т.к. данные пишутся по кольцу, то может произойти ситуация, когда обрабатывающий поток подзадержался и данные кольцевого буфера перетёрлись. Чтобы избежать этого я и делаю копирование вновь поступивших данных... Резюмирую: 1. По объективным причинам (архитектура железа) данные от продюсера необходимо копировать в некий буфер, при чём делать это нужно без локирования 2. Локировать желательно функциями/объектами WinAPI, а не объектами Qt 3. Чтобы избавиться от копирования на принимающей стороне ( m_outputBuffer ), возможно лучше пользоваться примерно такой ф-цией
и переделать m_outPtrs на std::queue или на std::list -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
||||
|
|||||
| xvr |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Не совсем так - у вас сейчас постоянно создаются и удаляются вектора для собственно данных. Я предлагал данные копировать непосредственно в очередь:
Если сделать операции *push/*pop атомарными, то даже mutex не потребуется |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |