Скиповое читение

Тема в разделе "WASM.A&O", создана пользователем persicum, 17 апр 2009.

  1. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    есть такая практическая заморочка.
    Допустим имеется файл на 30 гект.
    Нужно чтать его с интерливом по схеме
    [block0][block30][block60]...
    [block1][block31][block61]...
    ......
    Это потому что памяти только 1Г =(((
    Опыт показывает, что скипуя таким образом скорость чтения снижается с 50 метров за секунду аж до 3 метров-в-секунду ...
    Вроде считываем те же 30 Г но тока за 5 часов=(((
    Толи кеш у винта виноват толи сик головок...

    Как с энтим можно бороться, такие мысли:
    1) попробовать транспонировать филес чтобы читать блоки подряд, но это требует места и времени. Изза фрагментации диска не факт что новые блоки ляжут хорошо, тем более что придется писать в несколько потоков.
    2) твердотелый винт? Не факт опять, у него тоже есть кеш наверняка
    3) Thread Building Block - не знаю что это такое
    4) какие нить winapi? Я пока только из языка высокого уровня умею файлы читать...
     
  2. TSS

    TSS New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    494
    это пять!
     
  3. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    TSS, посмотрел в Вики про TBB. Это чтото для многопроцессорности и не ясно как оно может помочь, да и сложно для таких чайников как я
     
  4. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    кури флаги CreateFile. FILE_FLAG_RANDOM_ACCESS и FILE_FLAG_NO_BUFFERING должны помочь.
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
  6. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Разрезать на три файла и разложить их на трёх винчестерах.
     
  7. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Спасибо за наводку. Попробовал FILE_FLAG_RANDOM_ACCESS... Никакого эффекта на скорость чтения не обнаружил. Вообще, флаг рекомендательный, если винда видит что файл дергают туда-сюда она сама может подстроить стратегию использования буфера?

    FILE_FLAG_NO_BUFFERING - это очень суровый флаг. Требует сначала определить размер сектора устройства, скажем 512 байт, потом выделить буфер по адресу кратному этому сектору и читать строго целое их число... Это жестоко

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

    G13 New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2006
    Сообщения:
    499
    Навскидку, случайная ссылка из Гугла: http://www.developing.ru/com/memory_mapped_files_01.html


    А вообще, почитайте уже Рихтера, раз под win32 пишете. Полезно.
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    persicum
    Без конкретизации алгоритма ничего толком не скажешь. Если алгоритм допускает блочную обработку, то ес-но ее и нужно использовать, т.е. ситывать сразу большие последовательные куски из файла и уже в памяти обрабатывать блоки в нужном порядке. При такой блочной обработке способ чтения блока особой роли не играет - можно и через ReadFile и через FileMapping. Но юзание Filemapping-а в лоб, т.е. сначала 0,30,60.. по всему файлу, затем 1,31,61... по всему файлу - ес-но ничего не даст
     
  10. ava

    ava New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2003
    Сообщения:
    169
    Пришла в голову дурацкая мысль... persicum, ты, наверное, используешь единственный файловый хэндл для чтения? Попробуй открыть N хэндлов, перемотай их, соответственно, на 0, 30, 60 и т. д. блок и поочередно читай из хэндлов последовательно. Интересно, как при этом изменится скорость?
     
  11. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    ava
    Гы-Гы :+))
    persicum
    Действительно leo прав - дело не в способе чтения, а в том что считываешь ты не 30Г а во много раз больше...
    "Виноват" конечно кэш, точнее несоответствие схем работы кэша и программы. Данные читаются блоками кратными одному или нескольким кластерам диска, но используется только их маленькая часть, а к тому времени как они опять понадобятся они давно вытеснены из кэша и опять читаются с диска.
    Можно попробовать прикрутить "своё кэширование", т.е. при первом заходе из каждого блока копируешь в памяти "подблок", так чтобы общее количество этих подблоков полностью умещалось в свободное ОЗУ (т.е. составляло 500-700М при 1Г общей памяти, иначе будет тормозить файл подкачки). Дальше работаешь с этими подблоками по своей схеме пока они не кончатся, и опять прогоняешь весь файл считывая очередную их партию. Конечно от замедления связанного с многократным считыванием файла ты не избавишься, но хотябы этот процесс можно сделать подконтрольным и выжать максимум не зависящий от особенностей чтения файла осью.
     
  12. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Проблема в том, что функционально связаны как раз блоки 1,30,60, но никак не блоки 1 и 2... У кого-нить есть винт Solid State или RAM-диск на материнке тоже технологии SSD?
     
  13. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    persicum
    Если расстояние между блоками меньше кластера диска (или той единицы чтения на которую расчитана используемая функция чтения), то ты полюбому пробежав по цепочке 1,30,60,... прочитаешь его весь. Но объём кэш не позволит тебе сохранить результаты чтения и в цепочке 2, 31, 61,... тебе опять придётся его читать. Я предлагаю частичное решение - во время прочтения 1,30,60, одновременно запоминать в ОЗУ буфере блоки 2, 31, 61,... 3,32,62... и т.д. насколько хватит свободного ОЗУ. А при втором, третьем и т.д. заходе уже брать их из этого буфера пока он не кончится. Понятно что все 29 цепочек сразу запомнить не получится, но даже если памяти хватит только на одну следющую цепочку получишь удвоение скрости за счёт того, что будешь читать 30Гб с диска не 30, а только 15раз.
    Кстати похоже в этом случае и разумное использование файла подкачки может оказаться вполне оправданным - он же как правило мало фрагментирован и будет работать быстрее лишнего пробега по файлу, особенно с учётом "плотного" размещения в нём блоков. Т.е. даже если 1/30 (2х ускорение) или 1/15 (4х ускорение) часть файла не помещается в свобдное ОЗУ, не заморачиваться на этом факте, а поручать системе использовать подкачку будет вполне приёмлимо.
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    persicum
    Это не проблема. Проблема в том, что ты с этими блоками делаешь. Например, если по этим блокам считать какой-то хэш, сумму, макс\мин и т.д. и т.п., или любые другие действия в результате которых для для хранения промежуточных рез-тов требуется много меньше памяти, чем суммарный размер этих блоков, то проблемы собс-но и нет. Просто вместо обработки одной серии блоков нужно "параллельно" выполнять и копить рез-ты обработки 29 серий
     
  15. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Согласен, целью такого "противоестественного" чтения является собрать все нужные данные чтобы сразу вычислить функцию за один раз вместо того чтобы вычислять одновременно 30 функций но с частичным набором данных, что еще требует сильно голову поломать как это можно сделать. А что тут такого? Ведь это гораздо проще. Это все винт виноват как механическое устройство хотя и с произвольным доступом, но на самом деле любящим чтобы с него читали только подряд. Я же не прошу его терабайт считывать, я только хочу с него 30 гигов считать, а он зараза считывает 30 раз по 30.

    Буду смотреть в сторону SSD, может поможет.
     
  16. Prohvost

    Prohvost New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    107
    хрень какая-то... а может код покажешь?
     
  17. PSR1257

    PSR1257 New Member

    Публикаций:
    0
    Регистрация:
    30 ноя 2008
    Сообщения:
    933
    Почему нет? Это же один простой цыкл. В файл, кстати, можно писать "с дырками" - наверное лучше MemoryMapped - если сразу "дать понять" планировщику что файл будет "очень большой" записав последний блок - может он разбереццо как лучше распределить файл на винте.
     
  18. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Винту пофиг чего и как читать. Но у него как у механического устройства есть принципиальные механические ограничения, обойти которые каким-то чудесным образом просто невозможно. Из-за принципиальных физ.ограничений современные диски и ОЗУ не сильно отличаются по скорости\латентности произвольного доступа от своих собратьев 10-летней давности. Для дисков это ограничение на скорость вращения 7600 или 10000 об/мин и на время перемещения головок ~8-10мс, а для ОЗУ это задержка переключения вентилей ~4-7 нс. Поэтому все современные "заоблачные" скорости чтения\записи и HDD и особенно ОЗУ достигаются только при последовательном доступе и обязаны специальным ухищрениями - в HDD чтением за один раз целиком всей дорожки, а в ОЗУ чтением всей строки матрицы RAM с последующей передачей прочитанных данных на "офигенной" скорости, во много-много раз первышающей скорость произвольного\первоначального доступа. Поэтому нужно не "бицца качаном ап стену", требуя от HDD и DRAM невозможного, а сказать спасибо гению инженерной мысли за то, что несмотря на физ.ограничения удалось хотя бы для последовательного доступа повысить скорость чиения\записи на порядок с лишним.
    Резюме: современные устройства с произвольным доступом не гарантируют того, что скорость произвольноо и последовательного доступа будет одинаковой, хочешь непременно произвольный - получи свои ~3Mb/s и не вякай :)