Как организовать обработку?
От: a_g_e_n_t  
Дата: 11.10.06 15:38
Оценка:
Здраствуйте всем!

Коротко изложу суть моей проблемы:

У меня есть плата, с которой через DMA постоянно поступают данные... Скорость — примерно 10МБ/с.
Моя задача постоянно их обрабатывать и выводить информацию на экран. Сложность в том, что я не успеваю этого делать, однако процессор загружается максимум на 50-60%... ж/д задействован по-минимуму. Компьютер достаточно мощный, оперативки — 2ГБ

Сейчас обработка организована следующим образом:
Windows XP, VS 2005, C#.
В одном единственном потоке по событию плата выдает массив данных и я его обрабатываю,
Однако, не успеваю и теряются куски данных...
Приоритет потока Highest,приложения Real-Time. При этом процессор не загружен полностью(<=60%)... Я уверен, можно что успеть обработать такой поток.... Не пойму в чем проблема.....

Либо виндоус не дает мне больше процессорного времени, либо надо сделать обработку многопоточной, либо вынести в отдельный поток только получение данных с платы.

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

Помогите, как лучше организовать обработку?

Заранее всем спасибо!
Re: Как организовать обработку?
От: KolanT  
Дата: 11.10.06 16:58
Оценка: +1
___>максимум на 50-60%... ж/д задействован по-минимуму. Компьютер достаточно мощный, оперативки — 2ГБ

Было бы 100 с таким приоритетом, ты бы мышкой с трудом двигал...


___>В одном единственном потоке по событию плата выдает массив данных и я его обрабатываю,

___>Однако, не успеваю и теряются куски данных...

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


___>Некоторые советуют мне получать данные в одном потоке, а обрабатывать в другом...

___>Но я боюсь, что обмен между потоками через память будет очень накладным.....

Не бойся не будет...
Re: Как организовать обработку?
От: Mazay Россия  
Дата: 11.10.06 18:41
Оценка:
Здравствуйте, a_g_e_n_t, Вы писали:

___>Моя задача постоянно их обрабатывать и выводить информацию на экран. Сложность в том, что я не успеваю этого делать, однако процессор загружается максимум на 50-60%... ж/д задействован по-минимуму. Компьютер достаточно мощный, оперативки — 2ГБ


Скорее всего у тебя Pentium 4 с HyperThreading или какой-нить другой камень дающий два процессора (посмотри в Диспетчере устройств). Тогда действительно в 1 поток можно загрузить не более 50% камня (это если верить Диспетчеру задач).
На счёт накладных расходов на межпотоковое взаимодействие: один поток вычитывает данные (кстати, как и откуда?) в буфер в ОЗУ, а другой обрабатывает эти данные. Синхронизацию делай по заполнению половинки буфера. Т.е. заполнилась как половина буфера 1-м потоком он пнул второй, а пока второй обрабатывает данные, первый заполняет 2-ю половину. При этом 2-й поток должен обрабатывать данные заметно быстрее, чем 1-й их записывает в буфер. Чтоб минимизировать издержки на синхру увеличивай размер буфера. Если совсем туго — то юзай критические секции — они вроде бы самые дешёвые.
Кстати, в чём выражается потеря данных? Как ты это диагностируешь? Чё за железяка?
Главное гармония ...
Re[2]: Как организовать обработку?
От: Аноним  
Дата: 11.10.06 18:47
Оценка: +1
Здравствуйте, KolanT, Вы писали:

___>>Некоторые советуют мне получать данные в одном потоке, а обрабатывать в другом...

___>>Но я боюсь, что обмен между потоками через память будет очень накладным.....

Правильно советуют — один поток записывает из карты в буфер, другой обрабатывает и т.д. Буфер — это очередь. Однако очередь способна скомпенсировать временные рассогласовании в скоростях. Если скорость поступления данных всегда превышает скорость обработки, то очередь будет постоянно расти, пока память не кончится.
Re: Как организовать обработку?
От: GlebZ Россия  
Дата: 12.10.06 09:19
Оценка: 3 (2)
Здравствуйте, a_g_e_n_t, Вы писали:

___>Windows XP, VS 2005, C#.

Не очень хороший выбор для RealTime приложения. В данном случае нужно иметь как минимум два проца и серверный режим чтобы GC не останавливал работу во время сборки мусора. Фактически нагрузку ты можешь посмотреть через Perfomance Monitor. Особенно обрати внимание на процент GC.
Насчет буферизации тебе уже описали Re: Как организовать обработку?
Автор: Mazay
Дата: 11.10.06
. Единственное замечание — лучше иметь несколько буферов и переключать обработку и получение. Буфера должны быть достаточно большими чтобы они лежали в Large Memory второго поколения. Допустим открываем два буфера по 1 Mb организованные в кольцо. Поток который читает помечает буфер как буфер в работе. Поток который пишет записывает другой буфер и смотрит не обрабатывается ли в данный момент следующий буфер. Если он обрабатывается — то создается новый буфер, вклеивается в кольцо и уже в него идет запись. Время на синхронизацию и выделение памяти минимально.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Как организовать обработку?
От: Аноним  
Дата: 12.10.06 15:43
Оценка:
Здравствуйте, Mazay

Вы раскрыли мне глаза:
___>>Скорее всего у тебя Pentium 4 с HyperThreading... в 1 поток можно загрузить не более 50% камня

Да, у меня Pentium 4 с HyperThreading...... Как его лучше нагружать, чтобы задействовать весь ресурс?

___>>один поток вычитывает данные (кстати, как и откуда?)


Данные считываю с платы через сигнализацию WaitForSingleObject... Драйвер заполняет внутренний буфер и выставляет мне событие о том, что надо считывать

>>Кстати, в чём выражается потеря данных? Как ты это диагностируешь? Чё за железяка?

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

Сегодня разбил на 2 потока:
Сделал буфер из 3 кусков по 10МБ (byte[3][1024*1024*10])
И 3 события.....
В одном потоке — данные считываются поочередно в каждый кусок в цикле и выставляются соответствующие им события, символизируя, что можно обрабатывать...
Другой поток в цикле через WaitForSingleObject ждет эти 3 события и обрабатывает соответствующие куски....
Второй поток как бы следует за первым......

Вообще, синхронизация потоков через Event и WaitForSingleObject это не накладно?

Система стала работать значительно быстрее и стабильнее, но проц загружается максимум на 60-65%

Судя по
___>>в 1 поток можно загрузить не более 50% камня
Наверное, обрабатывающий поток использует все 50%, а остальные 10-15% на считывающий поток + система

Видимо, придется делать несколько обрабатывающих потоков....
расспаралелить обработку представляется возможным.....
Повторюсь:Как лучше загрузить Pentium 4 с HyperThreading? Какие соображения, может сталкивались?

Заранее спасибо.....
Re[2]: Как организовать обработку?
От: a_g_e_n_t  
Дата: 12.10.06 15:53
Оценка:
Здравствуйте, Mazay

Вы раскрыли мне глаза:
___>>Скорее всего у тебя Pentium 4 с HyperThreading... в 1 поток можно загрузить не более 50% камня

Да, у меня Pentium 4 с HyperThreading...... Как его лучше нагружать, чтобы задействовать весь ресурс?

___>>один поток вычитывает данные (кстати, как и откуда?)


Данные считываю с платы через сигнализацию WaitForSingleObject... Драйвер заполняет внутренний буфер и выставляет мне событие о том, что надо считывать

>>Кстати, в чём выражается потеря данных? Как ты это диагностируешь? Чё за железяка?

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

Сегодня разбил на 2 потока:
Сделал буфер из 3 кусков по 10МБ (byte[3][1024*1024*10])
И 3 события.....
В одном потоке — данные считываются поочередно в каждый кусок в цикле и выставляются соответствующие им события, символизируя, что можно обрабатывать...
Другой поток в цикле через WaitForSingleObject ждет эти 3 события и обрабатывает соответствующие куски....
Второй поток как бы следует за первым......

Вообще, синхронизация потоков через Event и WaitForSingleObject это не накладно?

Система стала работать значительно быстрее и стабильнее, но проц загружается максимум на 60-65%

Судя по
___>>в 1 поток можно загрузить не более 50% камня
Наверное, обрабатывающий поток использует все 50%, а остальные 10-15% на считывающий поток + система

Видимо, придется делать несколько обрабатывающих потоков....
расспаралелить обработку представляется возможным.....
Повторюсь:Как лучше загрузить Pentium 4 с HyperThreading? Какие соображения, может сталкивались?

Заранее спасибо.....
Re[3]: Как организовать обработку?
От: KolanT  
Дата: 12.10.06 16:07
Оценка:
Здравствуйте, a_g_e_n_t, Вы писали:

___>Повторюсь:Как лучше загрузить Pentium 4 с HyperThreading? Какие соображения, может сталкивались?


Потоки, потоки...

Может еще и алгоритм обработки не самый быстрый...
Re[3]: Как организовать обработку?
От: Mazay Россия  
Дата: 12.10.06 16:54
Оценка:
Здравствуйте, a_g_e_n_t, Вы писали:

___>Данные считываю с платы через сигнализацию WaitForSingleObject... Драйвер заполняет внутренний буфер и выставляет мне событие о том, что надо считывать

Ага! Часом не L-Card?
>>>Кстати, в чём выражается потеря данных? Как ты это диагностируешь? Чё за железяка?
___>У меня с платы идет в пределе бесконечно информации... чем больше успею обработать, тем лучше...
___>Задача выжать максимум из процессора, при этом не пропускать данные с платы.....
___>Поступающие данные синхронизированы — контрольный бит через каждые N бит..... Я постоянно контролирую, чтобы расстояние между контрольными битами не менялось....... Если оно изменилось, значит мы потеряли часть данных... Скорее всего не успели считать и часть данных перезаписалась.
___>При потере синхронизации, обработку продолжать невозможно.

Так, а как запоняется буфер-то? Драйвер что, маякнул тебе и в тот же буфер продолжает писать? Так не может быть — ты же должен сначала обработать данные, а то они затрутся. По идее драйвер и должен делать подобную буферизацию: в один буфер его поток пишет, а другой буфер ты обрабатываешь. Потом по сигналу драйвера меняете позу.

___>Вообще, синхронизация потоков через Event и WaitForSingleObject это не накладно?

При таком размере буфера можно забить.

___>Система стала работать значительно быстрее и стабильнее, но проц загружается максимум на 60-65%

___>Судя по
___>>>в 1 поток можно загрузить не более 50% камня
___>Наверное, обрабатывающий поток использует все 50%, а остальные 10-15% на считывающий поток + система
Угу. Раз прирост нагрузки о траспараллеливания небольшой, значит всё упирается в поток обработки.

___>Видимо, придется делать несколько обрабатывающих потоков....

Вот это, кстати, мысль.
___>расспаралелить обработку представляется возможным.....
везёт


Вообще, прежде чем делать что либо сделай замеры времени:
1) Максимальное время м/у сигналами от драйвера. Тупо запусти сбор данных и замеяй время м/у WaitForSingleObject. Данные не обрабатывай
2) Замерь максимальное время на обработку буфера данных равного по размеру буферу драйвера. Тупо в цикле пообрабатывай данные — пока забей на синхронизацию

Напиши сюда размеры буфера драйвера и результаты замеров времени. Да, и напиши подробнее на счёт взаимодействия с драйвером, бо, так как я понял то что ты написал, оно работать не может. Может пример кода.
Главное гармония ...
Re: Как организовать обработку?
От: c-smile Канада http://terrainformatica.com
Дата: 12.10.06 23:20
Оценка:
Здравствуйте, a_g_e_n_t, Вы писали:

___>Сейчас обработка организована следующим образом:

___>

...C#


А лучше для real-time обработки ничего не нашлось?
Re[2]: off
От: mrozov  
Дата: 13.10.06 09:55
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, a_g_e_n_t, Вы писали:


___>>Сейчас обработка организована следующим образом:

___>>

...C#


CS>А лучше для real-time обработки ничего не нашлось?



Ну не на C++ же писать в 21-ом то веке?
Re[2]: Как организовать обработку?
От: Mazay Россия  
Дата: 13.10.06 11:32
Оценка:
Здравствуйте, c-smile, Вы писали:

___>>Сейчас обработка организована следующим образом:

___>>

...C#

CS>А лучше для real-time обработки ничего не нашлось?

Да какая разница. Лишь бы успевал обрабатывать. Только буфер побольше завести чтоб дать GC поработать. Если уж на то пошло, то Винда вообще не реалтаймовая.
Главное гармония ...
Re[3]: off
От: remark Россия http://www.1024cores.net/
Дата: 15.10.06 09:15
Оценка:
Здравствуйте, mrozov, Вы писали:

M>Здравствуйте, c-smile, Вы писали:


CS>>Здравствуйте, a_g_e_n_t, Вы писали:


___>>>Сейчас обработка организована следующим образом:

___>>>

...C#


CS>>А лучше для real-time обработки ничего не нашлось?



M>Ну не на C++ же писать в 21-ом то веке?


На c++/cli


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Как организовать обработку?
От: Аноним  
Дата: 16.10.06 08:24
Оценка:
Здравствуйте, a_g_e_n_t, Вы писали:

___>Сейчас обработка организована следующим образом:

___>Windows XP, VS 2005, C#.
___>В одном единственном потоке по событию плата выдает массив данных и я его обрабатываю,
___>Однако, не успеваю и теряются куски данных...
___>Приоритет потока Highest,приложения Real-Time. При этом процессор не загружен полностью(<=60%)... Я уверен, можно что успеть обработать такой поток.... Не пойму в чем проблема.....

Дык, плата не будет ждать, пока ты данные обработаешь. Она скорее всего фигачит без перерыва.

___>Либо виндоус не дает мне больше процессорного времени, либо надо сделать обработку многопоточной, либо вынести в отдельный поток только получение данных с платы.


___>Некоторые советуют мне получать данные в одном потоке, а обрабатывать в другом...

___>Но я боюсь, что обмен между потоками через память будет очень накладным.....

1. Правильно советуют.
2. Таки "память" у разных потоков одного процесса общая.

___>Помогите, как лучше организовать обработку?


Создаешь пул "обрабатывающих" потоков. Данные считываешь отдельным потоком — "читателем". Получил некоторый достаточный обьем данных, находишь "обрабатывающий" поток, который в данный момент ничего не обрабатывает — подписываешь его на обработку. Если "читатель" не будет успевать ловить данные, ему можно поднять приоритет или соотв. понизить проиоритет остальным.
Когда поток обработал свою часть данных, он сигналит отдельному менеджеру (возможно тоже пул потоков), чтобы тот разобрался с обработанными данными. Учти "обрабатывающие" потоки могут заканчивать обработку данных совсем не в той последовательности в какой ты раздавал им работу. Т.е.

Обработка:
выдал 1му
выдал 2му
выдал 3му

Запросто может закончиться так:

отработал 3й
отработал 2й
отработал 1й

Настоятельно рекомендую к прочтению соотв. разделы книжицы тов. Рихтера advanced win32 (не знаю какая ее редакция на русском последняя). Без этих знаний пророчу полный провал.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.