Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Чтение памяти PCI-устройства  (Прочитано 12142 раз)
0 Пользователей и 1 Гость смотрят эту тему.
iFil
Гость
« : 27-09-2005 12:57 » 

Имеется самодельное PCI устройство без функций мастера (контроллер PCI - на ПЛИС Altera). Устройство имеет 32к памяти, которую необходимо читать (желательно быстро). Чтение я делаю в DPC (прерыванием устройство сообщает о готовности данных). Сделал несколько вариантов чтения: READ_REGISTER_BUFFER_ULONG (который в конце концов реализуется через rep movsd), через регистры MMX (movq/movntq), через регистры SSE (movaps), SSE + prefetcht0 (т.е. с кэшированием). Результаты следующие: чтение через MMX работает почти в 2 раза быстрее movsd, SSE - еще немного быстрее (процентов на 10), prefetcht0 ничего не дает. Кроме того, результаты на разных компьютерах отличаются. Скорость зависит от производительности компьютера и от того, через сколько мостов подключено устройство. В первом варианте (Pentium II, между устройством и процессором - только Host brige) среднее время чтения (movsd) - 4550 мс. В других вариантах - PIII, PIV и Athlon64 (устройство везде было подключено еще через 1 мост) скорости порядка 6000 - 9000 мс. Таким образом количество мостов играет решающее значение.
Итак, вопрос:
Можно ли ускорить скорость чтения?
Насколько я понимаю, большинство мостов PCI содержит механизм упреждающего чтения (кэширования), управляемый через регистры prefetchable memory base register и prefetchable memory limit register, в которые заносятся адреса начала и конца памяти, для которой разрешено упреждающее чтение. Кто ответственен за запись туда необходимых значений? Логично было бы если бы BIOS при загрузке или Windows делали это. Вероятно, сделать это несложно - в процессе перечисления PCI-устройств и распределения адресного пространства. У каждого блока PCI-памяти есть адрибут prefetchable, который указывает, можно ее кэшировать или нет (мои 32к можно). Можно было бы все prefetchable-области за мостом кинуть в одну область адресного пространства, а остальные -  в другую. Однако этого, видимо, не происходит. Могу ли я самостоятельно туда что-то записать? Во что в таком случае мост будет превращать обычные PCI-команды "Memory Read" - "Memory Read Multiple" или "Memory Read Line"? Насколько я знаю, мое устройство "Memory Read Line" (чтение строки кэша) не поддерживает. Ну и prefetcht0 из-за этого вероятно не работает (а вообще prefetcht0 для PCI- памяти работает или нет?).
И еще: имеется ли возможность (и смысл) использовать системный контроллер DMA для PCI устройства? Транзакции будут 16-битными, но зато Memory Read Multiple может быть заработает? Ведь теоретичестая скорость 32бит@33МГц@32кБ - порядка сотен мкс, и даже если скорость будет в 2 раза меньше теоретической, то меня это устроит.
Заранее спасибо.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 27-09-2005 15:50 » 

Пардон за вопрос... а зачем вы чтение в DPC делаете?Не понял почему не в ISR?!
это вопервых... во вторых - вы как скорость передачи измеряете?
к слову... если поток прерываний в ПК будет порядка килогерца хотябы... - машина встанет и без чтения 32кб памяти.
на собственном опыте проверял)) пытался то же самое сделать, только памяти у меня 1к был...
PS.
по поводу DMA - не совсем понял... Бус мастер на PCI? - по нему пробовал перекачивать порядка 30Мб/сек в комп, с паралельной записью на диск... ресурс ЦП  -при этом используется на 1%)))
можно наверное и больше... но как гворится больше смысла не имело - девать некуда)
« Последнее редактирование: 27-09-2005 15:57 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
iFil
Гость
« Ответ #2 : 28-09-2005 05:49 » 

Сразу извиняюсь, все приведенные времена - в микросекундах (у меня мс понаписано).
Сначала действительно я читал в ISR (разницы по скорости никакой). Но потом я сделал несколько вариантов чтения (режим выбирается из тестовой программы), по большей часьтю с MMX и SSE, а там состояние сопроцессора сохранять надо, а его выше DISPATCH_LEVEL сохранять нельзя (да и сопроцессор использовать, вероятно, тоже), пришлось в DPC перейти.
Частота прерываний регулируется из тестовой программы (максимум около 100Гц). Машина встает, если период прерываний меньше времени чтения (я пробовал задавать период 1 мс), все вешалось. Но, правда, если читать данные в DPC, то хотя бы SoftIce выплыть может, а выше ISR он не прыгнет (уж не знаю, по какого IRQL он допрыгнуть может, вероятно до ISR клавиатуры).
Bus Master мне автор железяки делать не хочет, говорит сложно очень. Я хочу узнать, можно ли из PCI-устройства читать системным (ISA) контроллером DMA. Ведь ему, вероятно, по барабану, какую память копировать. Только у него каналы есть на 8 и на 16 бит, но скорость вероятно все равно возрастет значительно. Может у кого такой опыт есть?
« Последнее редактирование: 28-09-2005 05:53 от iFil » Записан
dachny
Гость
« Ответ #3 : 29-09-2005 04:55 » 

Надо делать мастер но это уже не к Вам а к алтеристам которые делали ядро
если у альтеристов тяму мастер сделать нет надо менять альтеристов

Но ето все офтопик
Теперь топик

Не надо извращаться со всякими там MMX и SSE а надо пользовать функции HAL
Записан
iFil
Гость
« Ответ #4 : 29-09-2005 06:48 » 

Извращаться как раз надо, т.к. макисмум, что испольуют функции HAL - это movsd, а это простое 32-битное копирование, которое PCI host brige превращает в обычные команды read memory. Ну а мне надо заставить его использовать команды read multiplie или read line которые физически на шине быстрее выполняются (когда много данных прочитать надо). Когда пишешь в PCI, то все проще, процессор данные буферизирует и мало-мальски умный мост сам одиночные транзакции в пакетные упаковывает.
Использование MMX и SSE дает прирост в скорости практически в 2 раза, потому как внутренняя шина в современных процессорах 64-разрядная и тут уж, видимо, минимальная упаковка делается. (в MMX регистры 64-битные, в XMM - 128-битные, но скорость при их использовании практически одинаковая). Но как заставить проц длинную команду сделать? Возможно, при использовании команды prefetcht0 (это команда кеширования из SSE) генерится команда read line (это транзакция чтения строки кеша)? Но я этого этого проверить не могу, т.к. мое устройство read line не поддерживает (а read multiplie - да). Вероятно, ввести поддержку read line проще, чем сделать мастера шины, но стоит ли это делать?
И еще один вариант. В PCI мостах (и в моем в том числе) есть механизм чтения prefetchable memory (это память, которую можно читать вперед без запроса, т.е. кэшировать). Можно ли из драйвера модифицировать регистры моста, отвечающие за этот механизм? И во что мост будет превращать простое read memory - в read line или read multiplie?
Записан
dachny
Гость
« Ответ #5 : 29-09-2005 06:59 » 

>>Использование MMX и SSE дает прирост в скорости практически в 2 раза

Вам надо делать мастер а не тратить время на реверс инжиниринг HALа у Винды

Использование PCI интефейса без изпользования главной фичи PCI басмастеринга бессмысленно
 если Вам басмастеринг не нужен то и PCI Вам не нужно тоже
Записан
dachny
Гость
« Ответ #6 : 29-09-2005 07:07 » 

>>И еще: имеется ли возможность (и смысл) использовать системный контроллер DMA для PCI устройства?

системный контроллер DMA к PCI никагого отношения не имеет
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 29-09-2005 13:53 » 

что касательно DMA...
в свое время переписывал драйвер для ISA карточки L-Carda. там как раз использовались DMA каналы... в 95 винде. так вот насколько я тогда узнавал, штука это донельзя простая и представляет из себя банальный счетчик, который просто следить за автоматическим инкрементом читаемого или записываемого адреса в контроллере записи на ПК - его просто надо инициализировать. во ВСЕМ остальном - процедура аналогична чтения порта I/O, но поскольку реализация аппаратная - позволяет на ISA получить выигрышь по скоросте - сколько у меня тоглда получилось я честно говоря не помню, кажется до 200кГц - но вот чего?Ага). А родной драйвер LCarda на тех скоростях при оцифровке потока - терял отсчеты, отсюда и задача встала.
на PCI - насколько я понимаю то что называют DMA и сама виндовая функция DMAAdapter->DmaOperations->AllocateCommonBuffer
просто размещает заданный объем памяти по непрерывним ФИЗИЧЕСКИМ адресам, чтобы бусмастеру PCI было проще записывать в память ПК по инкременту. если бусмастер PCI платы умный - ему даже рваное(физически) адресное пространство подойдет, только таблицу физических адресов надо построить(ScatterGather так называемый).
аналог DMAAdapter->DmaOperations->AllocateCommonBuffer функции - размещение памяти по непрерывным физ адресам, в некешируемой области и получение физического его адреса на шине. Все это можно кстати и другими функциями винды реализовать. вышеуказанная функция, всего лишь, в одном вызове все это делает. ВСЕ остальное делает контроллер PCI на плате.
может ли мост конвертировать одиночные запросы в линейное чтение - не помню...  в одном из внутренних регистров контроллера PCI платы лежит флаг Prefetchable - поинтерисуйтесь стоит он или нет? Софтайс его показывает по команде "pci" Ага (я не про альтеру, а про стандарт PCI)
типа такого: "Base addres 0:   E4000000              64Mb   Memory 32-bit     Prefetchable"
ИМХО системный контроллер DMA - вам не поможет.
удачи!
« Последнее редактирование: 29-09-2005 13:56 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
iFil
Гость
« Ответ #8 : 30-09-2005 06:59 » 

Ну да, эта область памяти в устойстве помечена как prefetchable. Но этот флаг - всего лишь указание мосту, можно ли ее читать "вперед", т.е. кэшировать. А у моста есть пара регистров, в которых лежит начало и конец памяти, которая prefetchable. Так вот, в этих регистрах у меня нули. Вообще в "глупых" мостах эти регистры не реализованы и там всегда нули. Но у меня мост нормальный, у меня на него документация есть. SoftIce  конфигурационное пространство PCI-устройств только прочитать может. Так вот, если я в эти регистры грамотные значения запишу, то наверняка кэширование заработает. Только вот как это грамотно сделать? И почему не делается автоматически (BIOS-ом или Windows-ом)? В спецификации PCI-to-PCI не очень понятно написано  про механизм prefetchable.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 02-10-2005 09:55 » 

У вас когда PNP вклчюается и вы CM_PARTIAL_RESOURCE_LIST получаете, там в
CM_PARTIAL_RESOURCE_DESCRIPTOR (при CmResourceTypeMemory)
флаги какие стоят?
CmResourceTypeMemory:
    CM_RESOURCE_MEMORY_READ_WRITE The memory range is readable and writable.
    CM_RESOURCE_MEMORY_READ_ONLY The memory range is read-only.
    CM_RESOURCE_MEMORY_WRITE_ONLY The memory range is write-only.
>  CM_RESOURCE_MEMORY_PREFETCHABLE The memory range is pre-fetchable.
>  CM_RESOURCE_MEMORY_COMBINEDWRITE Combined-write caching is allowed.
    CM_RESOURCE_MEMORY_24 The device uses 24-bit addressing.
>  CM_RESOURCE_MEMORY_CACHEABLE The memory range is cacheable.
это первое...
второе.
если они не стоят - попробуйте HalAssignSlotResources или IoReportDetectedDevice/IoReportResourceForDetection?? или типа того сделать... и при вызове флагами поиграться. наверное по  IRP_MN_START_DEVICE надо делать... но не факт...
если честно я уже с трудом помню когда их менять можно.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines