Много лет проблема стоит для Windows. (И для Linux тоже.)
Запись в память устройства по PCI ещё как-то устраивает через оптимизированный код в memcpy(), где применяются команды по 8 и 16 байт за такт.
А вот читать уже на порядок медленнее, даже порциями по 16 байт, там хочется слепить соседние запросы в burst-транзакции, чтобы стало похоже по эффективности на запись.
В идеале -- надо запустить свободный системный канал DMA (их масса на материнке) "туда" или "обратно", самому заняться другими делами, а по готовности операции уже вернуться обратно на готовое.
Наверняка кто-то уже решал подобную задачу. Или MS где-то припрятала такой функционал ? Базовая вещь.
Физические адреса в устройстве есть, они непрерывные.
У нас в памяти виртуальные непрерывны, а физические попутаны, как ОС раздаст, но с этим ядро ОС разбирается хорошо.
К физическим и вообще аппаратуре не подпускают из верхнего уровня приложений, нужен драйвер.
Писал уже кто-то такое "на продажу" ? Чтобы не ходить по граблям в 1000...-й раз, вызвать функцию волшебного драйвера и забыть...