Добрый день.
Имеется самодельное 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 раза меньше теоретической, то меня это устроит.
Заранее спасибо.