varnie В общем лично я бы проводил чтение по 1 - 4 мегабайт, распараллеливая его с парсингом считанных данных. Хотя в принципе при выборе размеров кусков можно начинать с 64 КБ (и далее кратно этому значению). В любом случае при распараллеливании потери времени на считывание данных возникнут только при первом чтении, т.к. вряд ли парсинг будет занимать меньше времени, чем считывание.
varnie Каков вопрос - таков и ответ То вообще беспочвенные рассуждения, то конкретная цифра "до неск килобайт (теоретически)", а теперь оказывается "теоретически может быть и неск. сотен килобайт". Ответ - пофиг, сколько там теоретически в максимуме может оказаться - нужно ориентироваться на некое разумное среднее и иметь в виду разумный максимум. Но в любом случае, если речь идет о десятках-сотнях килобайт, то нужно читать все целиком и не морочить себе и другим голову PS: Кстати, помимо чистого С++ не мешало бы и с физикой дружить . На одно только позиционирование головки HDD требуется десяток миллисекунд, а с учетом путешествия твоего запроса на чтение по недрам ОС и железу и того больше. В то же время скорость последовательного чтения современных HDD составляет 50-80 Мб/с и твои несколько сотен Кб прочитаются за единицы миллисекунд - какое тут нафиг распараллеливание, асинхронное чтение или тем более потоки ?! l_inc Если только с FILE_FLAG_NO_BUFERING, т.к. при кэшируемом чтении винда при размерах блока более 64К "дуреет", т.к. не знает как ей быстренько "впихнуть" твои мегабайты в свой файловый маппинг блоками по 256К
leo я вас понимаю но меня зацепила выдержка, которую я привел в своем посте #13, и заставила задуматься: т.е. советуют читать поблочно. т.е. прочли блок, распарсили, далее берем след. блок. дык я и спрашиваю уважаемого всезнающего All -- для моей ситуации эта схема будет приемлема или нет? учитывая то что leo: выходит, что все это нафик не надо. считать за раз и дело с концом. так где же истина? ^_^
varnie Во-первых, советуют читать блочно по сравнению с дебильным вариантом т.е. посимвольного чтения с помощью АПИ ReadFile(hFile,buf,1,..), при котором львиная доля времени уходит на бестолковое переключение юзермод-кернелмод и обратно. Во-вторых, CRT-шные fgetc\getc и так читают средствами ОС достаточно большие блоки данных (у мелкософта по умолчанию 4К) в буфер потока и затем выдают юзеру по 1 символу уже из буфера. Причем размер буфера можно увеличить вплоть до считывания всего файла целиком вызовом setvbuf. Ну, и в третьих, опять же речь идет об общей схеме обработки без привязки к конкретным размерам - ты же не собираешься сотню-другую байт читать блоками ?! А для современных дисков и ОС также и файлы в единицы-сотни Кб тоже не имеет смысла дробить на блоки, т.к. за счет увеличения плотности записи и буферизации данных в контроллерах, скорости чтения и передачи данных существенно выросли, а вот время доступа к произвольному сектору осталось практически на том же уровне. Также и у современных ОЗУ на DDR\DDR2\DDR3 скорость пакетной передачи возросла до немыслимых ранее гиговых величин, а время случайного доступа (в ширпотребном майнстриме) изменилось незначительно и бултыхается на уровне сотни-другой мегагерц. Вывод- прикручивать асинхронное чтение и работу с двумя буферами имеет смысл только для достаточно больших многометровых файлов, а для единиц-сотен Кб - игра не стоит свеч. PS: Впрочем если хочешь поэкспериментировать, то пожалуйста - вот только не знаю, поддерживает ли С++ overlapped-чтение без привязки к ОС, т.к. с многопоточностью тут врядли что выиграешь
varnie С двумя буферами идея такая. Пока твоя задача обробатывает первый, во второй жесткий читает паралельно. Но тут нужно асинхронное чтение, а о таком я в виндоусе не слышал. Если кто знает как сделать подскажите. Но в любом случии что-бы чтение было оптимальным нужно делать чтение блоками. Оптимальный размер блока варьируется начиная от 64 кб так до 1мб.
Pavia Код (Text): HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...); BYTE *pBuf = new BYTE[1024 * 1024]; OVERLAPPED o = { 0 }; o.Offset = 1024 * 1024; // читаем файл со 2го мегабайта BOOL bResult = ReadFile(hFile, pBuf, 1024 * 1024, NULL, &o); DWORD dwError = GetLastError(); if (!bResult && (dwError == ERROR_IO_PENDING)) { // ждем завершения I/O bResult = WaitForSingleObject(hFile, INFINITE); } ...
Хэндл файла сигналит (хотя SYNCHRONIZE должен бы быть установлен автоматом..)? В каких случаях это просиходит? OVERLAPPED.hEvent не вернее?
что вы так прицепились к винде.. меня винда интересует в последнюю очередь если что т.к. пишу под *nix-ы и тестю в первую очередь на них, а потому и пишу на C++ используя STL.
varnie Вообще не понимаю о чем Ваша проблема (и почему Вы до сих пор не закрыли тему), если у вас файл меньше 1МБ. asmfan Дж. Рихтер, Дж. Кларк. Программирование серверных приложений для Windows 2000:
varnie истина в том, что для двух байт или сотни килобайт это без разницы. А вот начиная с десятка мегабайт начинает сказываться фрагментация, параллельно-конкуририрующее чтение/запись (в своп напр) итд. схема которую я привел выше целиком и полностью выдрана из описалова работы буферов директ соунда. Ну и потом, как бы быстро не читал винт, требования могут быть еще выше. (не этот случай. 10 байт это не серьезно)
asmfan см пост #28. все это интересно, но мне фиолетово на Windows и её технологии, что я уже выше подчеркнул в этом топике.
varnie топик существует вне зависимости от создателя и от его восприятия цветов. фиолетовое вам не фиолетово другим читающим его. считайте мой пост не вам, а тем, кто будет читать этот топик.
asmfan Поскольку речь шла только о двух буферах, а не о "multiple asynchronous I/O operations", то ожидание на hFile в коде censored вполне уместно и правомерно
leo а я говорю обратное? там написано "добавка" а не опровержение) Иначе бы, после кода censored, смысла в Event'ах в OVERLAPPED струкруре совсем не было бы на первый взгляд. А так он появляется.
asmfan Ну дык, у меня тоже не "опровержение", а уточнение PS: Если уж "придираться", то к WaitForSingleObject и многоточию, т.к. по смыслу нужно бы запустить чтение нового блока и заняться обработкой предыдущего (многоточие), а по завершении обработки проверить\дождаться готовности нового блока по GetOverlappedResult