SCSI порт-драйвер и производительность
От: x64 Россия http://x64blog.name
Дата: 27.11.12 20:59
Оценка:
Привет.

Ситуация такая. Пишу полноценный SCSI порт-драйвер (не использующий ни ScsiPort, ни StorPort), работает всё замечательно на всех системах, но сильно проседает производительность на малых блоках (порядка 4 КБ). Архитектура вполне стандартная: есть драйвер виртуальной шины, на своей шине он обнаруживает опять же виртуальное дисковое устройство, которое сообщает о себе, как о GenDisk, в результате на него вешаются disk.sys, partmgr.sys и ещё classpnp.sys сбоку. Обрабатываю SCSI-команды плюс некоторые IOCTL, про PnP, Power и WMI и не говорю, это само собой. В качестве непосредственно хранилища данных у меня файл, память, сеть, в общем, всё, что угодно, только не реальная железка. Почему озаботился проблемой, потому что написанный мной же legacy виртуальный диск, который по уровню сидит примерно там же, где драйвер класса, выдаёт минимум в 2 раза большую производительность, на малых блоках в особенности, — хочется добиться того же, но с порт-драйвером, ну или хотя бы убедиться, что это нереально.

Теперь о том, что уже пробовал. Выставление полей MaximumPhysicalPages и MaximumTransferLength в структуре STORAGE_ADAPTER_DESCRIPTOR действительно влияет на производительность самым непосредственным образом, но, к сожалению, увеличение этих параметров имеет смысл только до определённого предела, во-вторых, это влияет только на ввод/вывод большими блоками. Реализация write-caching, когда запрос SCSIOP_WRITE завершается до того, как данные фактически записаны мною, даёт некоторый эффект только для записи и не всегда, мне же нужно и для чтения тоже. Реализация очереди pending-запросов вообще даёт обратный эффект, т.к. накладных расходов становится больше (об этом в следующем абзаце). Обработка mode sense/select с кодом caching никак не влияет на storage stack, по сути, это управление исключительно портом/железкой. Помимо прочего, пробовал работать с буфером pSrb -> DataBuffer напрямую, минуя MDL, это действительно даёт ещё некоторый прирост скорости, проблема в том, что в случае paging I/O этот буфер может быть не валиден, а вот корректно распознать paging I/O на этом уровне не всегда есть возможность, даже если использовать недокументированные флаги и кое-какую эвристику.

Отдельно про queueing пару слов. Поддержка command queueing или не реализована в Windows вообще, или я что-то делаю неправильно (а как правильно и возможно ли вообще на этом уровне — вопрос открытый), но так или иначе мне не удалось заставить этот механизм работать (ставлю CommandQueueing в TRUE в обоих дескрипторах в IOCTL). Смотрел исходники classpnp/disk в WDK, но то ли они не соответствуют действительности, то ли ещё что, но я не увидел там полноценной реализации этого механизма. Получается, что все запросы, которые драйвер класса шлёт (мини-)порту — они все untagged, что выливается в значениях QueueTag = 0, QueueSortKey = 0 и QueueAction = SRB_FLAGS_QUEUE_ACTION_ENABLE в структуре SRB (что означает, что queueing вообще-то включен и работает, но...), при этом тег всегда 0, во сколько бы потоков я не запускал стресс-тесты. Подозреваю, что эти значения не для порт-драйвера, а для кого-то ниже (железка?), но у меня нет никого ниже, шина чисто номинальная. Тут ещё такой момент (как раз про отложенную обработку) — по спецификации нельзя слать более одного untagged-запроса за раз, т.е. если ранее уже был послен untagged-запрос, то его необходимо дождаться, что драйвер класса и делает (вот тут он, зараза, следует спецификации по полной программе, где ж всё остальное-то), но проблема в том, что от него все запросы — untagged, поэтому он никогда не шлёт read/write-запросы пачками, всегда строго последовательно, например, если я вставлю задержку в 2 секунды в обработчик чтения, то и получать буду не более одного read-запроса в 2 секунды, что попахивает каким-то маразмом, по-моему.

Любые идеи приветствуются, включая грязнохаки, может где чего подкрутить можно, может я что-то очевидное упустил? Просьба не отсылать в поиск, в гугл и уж тем более на osronline.com, — это, кстати, отдельная песня, там этот вопрос обсасывался огромное кол-во раз, но никто из тамошних "гуру" так и не смог дать реально конкретный ответ на указанные выше вопросы. В гугле был и был много, информации крайне мало, что, в принципе, ожидаемо, т.к. порт-драйвера недокументированы, вместо них предлагается писать минипорты, которые мне в данный момент не подходят, да и совсем не факт, что они смогут обеспечить требуемую производительность. Исходники порт-драйверов в сети есть, видел пару, но там всё сильно упрощённо и авторы, похоже, о производительности не парились вообще.

Как-то так.
Заранее спасибо.
JID: x64j@jabber.ru
scsi порт-драйвер
Re: SCSI порт-драйвер и производительность
От: Ernesto  
Дата: 28.11.12 01:13
Оценка:
Здравствуйте, x64, Вы писали:

Так замеры скорости что показали? Например 450 метров в секунду выдает?
Re[2]: SCSI порт-драйвер и производительность
От: x64 Россия http://x64blog.name
Дата: 28.11.12 01:59
Оценка:
E>Так замеры скорости что показали? Например 450 метров в секунду выдает?

Да выдаёт-то он и 7 ГБ/с и даже больше, но это только на больших блоках (более 1 МБ), а вот если, скажем, по 4 КБ читать/писать, вот тогда проседает сильно, около 300 МБ/с. При этом мой legacy-диск на тех же 4 КБ блоках в том же тесте выдаёт вплоть до 2 ГБ/с. На данный момент ситуация такая, что драйвер класса всегда шлёт untagged-запросы и строго последовательно, в результате у меня не остаётся никакого пространства для манёвра, так бы может хоть очередь запилил, но смысл? Всё равно только один запрос за раз. А почему так — вопрос вопросов.
JID: x64j@jabber.ru
Re[3]: SCSI порт-драйвер и производительность
От: Ernesto  
Дата: 28.11.12 20:45
Оценка:
Здравствуйте, x64, Вы писали:

E>>Так замеры скорости что показали? Например 450 метров в секунду выдает?


x64>Да выдаёт-то он и 7 ГБ/с и даже больше, но это только на больших блоках (более 1 МБ), а вот если, скажем, по 4 КБ читать/писать, вот тогда проседает сильно, около 300 МБ/с. При этом мой legacy-диск на тех же 4 КБ блоках в том же тесте выдаёт вплоть до 2 ГБ/с. На данный момент ситуация такая, что драйвер класса всегда шлёт untagged-запросы и строго последовательно, в результате у меня не остаётся никакого пространства для манёвра, так бы может хоть очередь запилил, но смысл? Всё равно только один запрос за раз. А почему так — вопрос вопросов.


Ты своей утилитой тестируешь или из инета скачал? Просто хотел сравнить со своим драйвером, а писать не хочется замерялку.

ЗЫ: АТТО что то не хочет замеры делать, пока не разобрался в причине, скорее всего какие то характеристики диска не нравятся.
Re[4]: SCSI порт-драйвер и производительность
От: x64 Россия http://x64blog.name
Дата: 28.11.12 20:55
Оценка:
E>Ты своей утилитой тестируешь или из инета скачал?

CrystalDiskMark
Помимо прочего, приходится использовать и её.
JID: x64j@jabber.ru
Re[3]: SCSI порт-драйвер и производительность
От: Ernesto  
Дата: 29.11.12 02:33
Оценка:
Здравствуйте, x64, Вы писали:

E>>Так замеры скорости что показали? Например 450 метров в секунду выдает?


x64>Да выдаёт-то он и 7 ГБ/с и даже больше, но это только на больших блоках (более 1 МБ), а вот если, скажем, по 4 КБ читать/писать, вот тогда проседает сильно, около 300 МБ/с. При этом мой legacy-диск на тех же 4 КБ блоках в том же тесте выдаёт вплоть до 2 ГБ/с. На данный момент ситуация такая, что драйвер класса всегда шлёт untagged-запросы и строго последовательно, в результате у меня не остаётся никакого пространства для манёвра, так бы может хоть очередь запилил, но смысл? Всё равно только один запрос за раз. А почему так — вопрос вопросов.


Посмотрел на IRP/SRB запросы и вот что у меня получается. В среднем, на чистый запрос БЕЗ КОПИРОВАНИЯ данных уходит от 5 до 10 микросекунд. Пусть будит в среднем 7. Делаем расчет, сколько таких запросов пробежит в секунду:
1000000 / 7 = 143 000 (округлил)
Если взять в расчет размер блока в 4кб, то получается что без учета копирования данных верхняя планка скорости приблизительно на 560 метров. Получается все что ниже из за того что нужно еще и скопировать данные. Насколько я понял немало проседает скорость при переходе от IRP к SRB. Поэтому говорить не о каких 2 гигов в секунду тут и не приходится. На всякий случай мой стек:

\FileSystem\Ntfs
\Driver\volmgr
\Driver\Disk
SCSI Bus
Re[4]: SCSI порт-драйвер и производительность
От: x64 Россия http://x64blog.name
Дата: 29.11.12 03:10
Оценка:
E>Поэтому говорить не о каких 2 гигов в секунду тут и не приходится.

А ты железо попробуй обновить, боюсь, что тогда придётся. Но вопрос не об этом, ты лучше скажи, у тебя SCSIOP_READ/WRITE запросы от disk.sys также строго последовательно приходят или как?
JID: x64j@jabber.ru
Re[5]: SCSI порт-драйвер и производительность
От: Ernesto  
Дата: 29.11.12 13:29
Оценка:
Здравствуйте, x64, Вы писали:

E>>Поэтому говорить не о каких 2 гигов в секунду тут и не приходится.


x64>А ты железо попробуй обновить, боюсь, что тогда придётся. Но вопрос не об этом, ты лучше скажи, у тебя SCSIOP_READ/WRITE запросы от disk.sys также строго последовательно приходят или как?


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

Кстати, могу посоветовать одну прогу, которая при разработке всяких SCSI & Storage драйверов просто незаменима. busTRACE называется. Там очень наглядно показываются запросы.
Re[6]: SCSI порт-драйвер и производительность
От: x64 Россия http://x64blog.name
Дата: 29.11.12 15:55
Оценка:
E>Сейчас посмотрю запросы, только вот скажи когда смотреть, во время спидтеста или во время обычной работы.

Да без разницы, у меня всегда строго последовательно идут от disk.sys. Сделай откладывание запросов в очередь и вставь задержку в обработчике перед завершением запроса, сразу всё понятно станет.
JID: x64j@jabber.ru
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.