2013-11-23 1 views
0

Предположим, что большой файл сохранен на диске, и я хочу запустить вычисление на каждом фрагменте данных, содержащихся в файле.Использование прерываний при чтении файла с диска

Код C/C++, который я бы написал для этого, загрузит часть файла, затем обработает, затем загрузит следующую часть, затем обработает эту следующую часть и так далее.

Если меня заинтересовало это в кратчайшие сроки, я мог бы сделать следующее: во-первых, скажите DMA-контроллеру загрузить первую часть файла. Когда эта часть загружена, сообщите DMA-контроллеру, чтобы загрузить вторую часть (в некоторой другой части памяти), а затем сразу же начать обработку первой части.

Если я получаю прерывание от DMA во время обработки первой части, я завершаю первую часть, а затем передаю DMA, чтобы перезаписать ее третьей частью файла; затем обрабатываю вторую часть.

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

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

Вопрос: возможно ли это сделать: a) в C с использованием нестандартного расширения или b) в сборке? Или операционные системы вообще не допускают таких вещей? Вопрос подразумевается прежде всего в контексте с одним потоком, хотя мне также будет интересно узнать, как это сделать с помощью двух потоков. Кроме того, меня интересует конкретный код; это скорее теоретический вопрос.

+1

Разве это не те трубы, которые предназначены для операционных систем? –

+0

Вы слишком низкоуровневый для кода пользователя. Не забывайте, что ваше приложение работает не только, а дисковые контроллеры совместно используются. И вы действительно не знаете, где ваши данные находятся на диске в целом. Посмотрите на асинхронные I/O и/или файлы с отображением памяти и какие опции у вашей ОС есть для них. – Mat

+1

Любая нетривиальная операционная система уже работает именно так. Очень непонятно, почему вы думаете, что вам нужно помочь. –

ответ

1

Вы правы, что по умолчанию вы не получите этого, потому что чтение блокировки останавливает поток от выполнения какой-либо обработки. Ханс прав, что современные ОС уже заботятся обо всех мелких деталях процедур DMA и завершения прерываний.

Вам необходимо использовать описанную вами архитектуру, предварительно выдав запрос, когда вы будете использовать данные. Выдавать асинхронные запросы ввода-вывода (в Windows это называется OVERLAPPED). Тогда поток будет идти точно так, как вы предполагаете, но DMA и прерывания обрабатываются в драйверах.

В Windows, посмотрите на FILE_FLAG_OVERLAPPED (для CreateFile) и ReadFile (если вы, как события) или ReadFileEx (если вы, как обратные вызовы). Если вам не нужно обрабатывать данные в каком-либо конкретном порядке, добавьте порт завершения в микс, который ставит в очередь ответы на завершение.

В Linux, OSX и многих других Unix-подобных операционных системах смотрите aio_read. Или fadvise. Или используйте mmap с madvise.

И вы можете получить эти преимущества без написания собственного кода. ,NET недавно добавила метод ReadAsync к его FileStream, который может использоваться с продолжением стиля прохождения в виде объектов Task, с синтаксическим сахаром async/await в компиляторе C#.

0

Как правило, в многорежимной (пользовательской/системной) операционной системе у вас нет доступа к прямым dma или к прерываниям. В системах, которые расширяют эти функции из режима ядра (системы) до пользовательского режима, накладные расходы исключают возможность их использования.

Игнорирование того, что вы требуете, требует особо специализированной среды для поддержки, идея звучит и распространена: объявление двух (или более) буферов для включения DMA в следующий, когда вы обрабатываете первый. Когда используются два буфера, их иногда называют буферами пинг-понга.