Мне нужно написать процедуру (используя ассемблер + Win32 API), которая бы посчитала контрольные значения для указанного файла тремя способами. Размер файла не ограничивается, поэтому в общем случае можно считать, что его не удастся загрузить в память полностью. Во время своей работы процедура должна показывать объем выполненной работы в дочернем контроле progress bar. В общем, задачка довольно простая, но хотелось бы чтобы эта процедура была оптимизирована по скорости работы, и в то же время имела бы не большой размер кода (но оптимизация по скорости работы более важна). Также хотелось бы, чтобы она в полном объеме использовала ресурсы памяти установленной на компе, т.е. чтобы она при прочих равных работала бы быстрее на той машине, где установлено больше памяти. Процедура ориентирована для работы под Windows9x+ и Windows 2000+. Вот такая задачка. Процедуры для подсчета контрольных значений у меня есть. Осталось только разобраться, как в данном случае лучше всего организовать работу с файлом. Вообще-то я и сам могу это сделать, но у меня ещё мало опыта, поэтому мое решение, скорее всего, не будет оптимальным. Поэтому вопрос к вам: как в данном случае оптимально организовать работу с файлом?
А в чем проблема-то ? Как я понимаю, для расчета контрольных значений достаточно один раз прочитать файл блоками от начала до конца. Поэтому проблем с памятью вроде как и нет. Зависимости от размера установленной физической памяти реально тоже нет. В данном случае основной тормоз - это ИМХО скорость обмена с диском, особенно если файл фрагментирован. Так что ИМХО читай себе блоками по 16, 32 или 64 Кб, считай контрольные значения и не парься. Можно открыть файл с флагом FILE_FLAG_NO_BUFFERING - вроде как чуть быстрее получается. Но при этом адрес и размер буфера д.б. кратен 512 байт. Если использовать Buf=VirtualAlloc(Null,..) - автоматом получишь выравнивание на 64Кб.
leo Да нет, проблемы никакой нет. Просто хотелось бы узнать, как лучше всего это дело организовать. К примеру какой механизм работы с файлами больше подходит в данной ситуации: обычный (ReadFile, WriteFile), обычный с перекрытием (OVERLAPPED) или MMF? Также хотелось бы узнать, как можно подобрать оптимальный размер буфера (или буферов)? А что блоки то такие маленькие, или это не влияет на скорость? IMHO, если использовать механизм работы с файлами с перекрытием и сделать буфера достаточного размера, то можно подсчитывать контрольное значение для одного буфера, в то время как другой за это время будет заполнен следующим блоком файла. Спасибо за подсказку, я обязательно учту её.
Oleg_SK OVERLAPPED не поддерживается в 9x. Хоть Win98 и маст дай, но еще далеко не дед. <font color="gray]<font size=2>Windows Me/98/95: For asynchronous read operations, hFile can be a communications resource opened with the FILE_FLAG_OVERLAPPED flag by CreateFile, or a socket handle returned by socket or accept. You cannot perform asynchronous read operations on mailslots, named pipes, or disk files. Windows Me/98/95: For operations on files, disks, pipes, or mailslots, this parameter must be NULL; a pointer to an OVERLAPPED structure causes the call to fail. (GetLastError = ERROR_INVALID_PARAMETER = 87)</font><!--size--></font><!--color--> MMF в данном случае работает гораздо дольше. Попробовал для примера два файлика 70 и ~100Мб на разных компах, получилось в ~1.5 и ~2 раза дольше, чем обычное блочное чтение. Эти же примерчики показывают, что увеличение размера буфера свыше 32-64К практически ничего не дает. Кстати, выбор "маленьких" блоков хорош с точки зрения кэширования данных при расчете несколько контрольных значений (хотя повторная загрузка данных из памяти в кэш существенно быстрее чем чтение с диска, но все таки). Попробуй сам с разными размерами буфера. Для экспериментов кстати нужно обязательно использовать флаг FILE_FLAG_NO_BUFFERING, иначе после первого же прохода файл попадет в файловый кэш и результаты последующих чтений будут занижены. PS: Что-то народ безмолвствует на эту тему ...