LINUX.ORG.RU

Релиз shuf-t 1.2 — аналог shuf для файлов размером с RAM

 ,


2

12

Хочу представить публике утилиту shuf-t — аналог shuf (случайная перестановка строк файла) из GNU Core Utilities, предназначенный для работы с текстовыми файлами, размеры которых сравнимы или превышают доступную RAM.

Факты:

  • Shuf-t был написан с нуля на Qt5. Версия 1.2 перенесена на boost 1.5.8, без Qt. Но QtCreator \ qmake все еще используются для сборки.
  • Распространяется под лицензией Simplefied BSD.
  • Командный интерфейс совместим с shuf.
  • На данный момент доступен только deb пакет. Windows версия будет собрана позднее.
  • Для тасования строк использован алгоритм Фишера-Йетса

Кому мал shuf?

Основная сфера применения shuf-t — задачи машинного обучения. Конкретнее - подготовка данных для Vowpal Wabbit. Машинное обучение позволяет классифицировать (и не только) результаты на основе исторической выборки. Яркий пример — банковский скоринг (давать/не давать кредит). Чем больше результатов кредитования увидит классификатор — тем он точнее (обычно).

Столкнувшись с данными, объемом превосходящими RAM одного компьютера, экспериментатор вынужден обращаться к кластерам (MapReduce и т.п.) и облакам. Либо воспользоваться системами online machine learning, лучшей из которых сейчас является Vowpal Wabbit. Принцип VW — получил пример, обработал его и забыл. В памяти хранятся только коэффициенты результирующих уравнений, которые подгоняются по получаемым примерам. Т.о. VW может работать на одном ПК с наборами данных неограниченного размера.

У подобных систем есть минусы, и один из них — чувствительность к порядку предъявляемых для обучения классификатора данных. К примеру, если вы отсортируете ваш набор кредиторов по результату, и предъявите VW сначала 10000 неплательщиков, а затем 10000 исправно погасивших долг, то после обучения классификатор будет всех заносить в последнюю группу, т.к. о неплательщиках он давно «забыл». Выходом в данном случае является равномерное размазывание записей о плохих и хороших заемщиках по набору данных. Что и достигается рандомизацией порядка строк в текстовом файле размером в сотню гигабайт.

Как работает?

Очень просто - в RAM считываются не строки файла, а их адреса в нем. Их порядок рандомизируется. В соответствие с новым порядком строк исходный файл считывается в выделенный в RAM буфер и сохраняется, куда пожелал пользователь. Нюансом тут является то, что файл считывается в несколько проходов (т.к. буфер меньше его размера), а offset'ы строк сортируются так, что чтение всегда идет от начала файла к его концу. Т.е. не выполняется seek() адреса меньше текущей позиции чтения.

Скорость работы зависит от числа строк, их размера и меняется нелинейно. 4Гб файл с дефолтным буфером в 1Гб у меня обрабатывается 4 минуты.

>>> Проект на github



Проверено: Shaman007 ()
Последнее исправление: Truf (всего исправлений: 3)
Ответ на: комментарий от Truf

Мне кажется, вот этот мой вопрос потерялся. Можете прокомментировать?

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

в т.ч. налобаю прожку, которая покажет ответ на твой вопрос

вообще удивительно, чтобы до такого алгоритма никто не додумался — ты бы не мог поспрашивать где-нить в хороших местах, действительно ли такие алгоритмы не известны? (two-pass shuffle algorithm for string array that does not fit into ram, наверно так)

если мой алгоритм прокатит, то я предлагаю вместе написать пейпер

з.ы. я привык на «ты» общаться в инете (в обе стороны)

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от Truf

Надо - вышлю длины, как предложил www_linux_org_ru. А хотите - скачайте оригинал. Я бы на вашем месте скачал оригинал и не парился.

я уже писал, что скачать оригинал за реальное время не могу, так что жду архив с длинами строк (можно на гитхабе, например)

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Шаффлу на длин строк тоже пофиг.

совсем не пофиг

Во-первых надо договориться о терминах. Если речь о утилите в целом, то a) на данные всё равно пофиг и Вы это понимаете; б) прыгать всё равно придётся, столько же, если перенести прыжки из входного файла в выходной, (эту версию я уже отверг и на ftp у меня лежит версия без seek, а только offset к map), то прыжки получатся в выходном файле, к тому же дырявом вначале и жутко фрагментированным полностью заполненым в конце. Что ещё хуже. Хотя бы тем, что утилита становится нефункциональной: не работает с stdout, требует seekable на out и полученный результат в виде фрагментированного файла вас тоже не обрадует. Оригинальный автор вообще упирает на SSD, там прыжки уже пофиг, а вот на парсенье фрагментации уже совсем нет, да и если есть возможность переложить syscall на механизм paging-а, то почему бы и не?

Если речь о самом алгоритме перестановки, то там вся эта лабуда нужна только для одного - узнать сколько строк и не более того.

vodz ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

вообще удивительно, чтобы до такого алгоритма никто не додумался — ты бы не мог поспрашивать где-нить в хороших местах, действительно ли такие алгоритмы не известны? (two-pass shuffle algorithm for string array that does not fit into ram, наверно так)

Додумались. Как я уже говорил, у каждого экспериментатора свой костыль и он именно на эту тему: порезать, пошафлить по частям и собрать обратно. Обычно их пишут на Python. Но я не видел каких либо анализов и воспринимаю их как эвристику. (Попробую поискать) На самом деле, на практике такой подход годится. Сама необходимость в шаффлинге данных - уже workaround другой проблемы. Просто я считал, что и без распила файла смогу его пошафлить гарантированно нормальным алгоритмом достаточно быстро за счет seek'ов, но не учел paging ФС.

Truf
() автор топика
Ответ на: комментарий от Truf

Додумались. Как я уже говорил, у каждого экспериментатора свой костыль и он именно на эту тему: порезать, пошафлить по частям и собрать обратно. Обычно их пишут на Python. Но я не видел каких либо анализов и воспринимаю их как эвристику.

нет, *это* не называется «додумались»

«додумались» означает наличие пейпера (не важно где, можно на гитхабе, архиве, ... но пейпера) с

1. вычислительной моделью жесткого диска

2. описанием алгоритма шаффла

3. доказательством его несмещенности

4. скоростью работы алгоритма в рамках выбранной модели жесткого диска

это необходимый минимум; а эвристики это эвристики

и еще — то, что тебе этот алгоритм нужен как костыль, не означает, что в хорошем, некостыльном алгоритме шаффла нет ценности — она есть

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от www_linux_org_ru

Пейпер обрабатывает данные по мере поступления по определению. Нельзя сделать случайную перестановку, если не известно сколько всего элементов ещё будет. Так что если так хочется пейпер, то это будет супер костыль - пишем вход в tmp, потом по EOF работаем.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Хотя бы тем, что утилита становится нефункциональной: не работает с stdout, требует seekable на out и полученный результат в виде фрагментированного файла вас тоже не обрадует.

по-моему, без этого можно обойтись, но временные файлы все же *придется* писать если размер всех строк больше размера ram, а в этом случае можно тупо переписать и stdin, и stdout в файлы, и от ограничений якобы избавится

впрочем, это повлияет на число проходов по диску, так что некоторая разница есть

б) прыгать всё равно придётся, столько же

нет

но доказывать мне лень, легче предъявить че-нить, если оно у меня получится

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от Truf

А длины я залил сюда.

я че-то не понял... оно что ли не работает, если в браузере выключен ява-скрипт?! не годится, залей в другое место

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Truf

Нужно будет поискать вообще все по шаффлам.

я так полагаю, что правильнее будет задать вопрос на computer science @ stackoverflow, и может еще на kaggle (или где там ты тусуешься?), с упором не на эвристику, а на доказанный результат

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Truf

но не учел paging ФС

тебе мешает не ФС, а то, как устроены жесткие диски

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Truf

dfiles.ru тоже требуют ява-скрипт, и вообще не для опенсорса, а спираченного

почему ты не хочешь нормально положить этот файл на гитхаб, рядом со своей прогой? это же, фактически, тестовые данные для твоей проги, и никто не будет придираться к тому, как ты их получил (fair use я так полагаю)

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 3)
Ответ на: На mmap от vodz

Ну нате на mmap. ftp://ftp.simtreas.ru/pub/my/shuf-f.c никакого буфера нет, чисто mmap.

посмотрел

если я правильно понимаю, основная работа происходит здесь:

for(sz = l = 0; l < num_lines && sz < n; l++, sz++)
    full_write(f_out, map + shuffle[l].off, shuffle[l].lenght, out_name);

если я правильно понимаю, тут идут рандомные прыжки по замапленному файлу, чтение 1 строки, и последовательная ее запись в выходной файл

если файл раз в 20 превышает к-во оперативки на компе и средняя длина строки 200 байт, то вот мой прогноз:

1. на hdd эта хрень будет записывать выходной файл со скоростью 20 КБ/с

2. на ssd эта хрень будет записывать выходной файл со скоростью 10 МБ/с (если ssd держит 50 000 iops)

понятно, что при 16 ГБ памяти на компе и 10Гб файле все будет намного быстрее, но в таком случае интерес представляет 320ГБ файл, а не эти детсадовские песочницы

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от Truf

На stakoverflow спросил.

и как там дела? я по слову shuffle че-то не могу найти твой вопрос

кстати, твой алгоритм рассчитан на то, что *перестановка* не поместится в оперативку?

т.е. скажем при 4ГБ оперативке у нас имеется более 1 000 000 000 строк?

предлагаю для сравнения алгоритмов принять ограничения:

число_строк < 4 000 000 000

и

размер_оперативки > 4*число_строк

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

и как там дела?

Пока плохо.

твой алгоритм рассчитан на то, что *перестановка* не поместится в оперативку?

Не рассчитан. На практике я ограничивался ~15 000 000, но правда, строки были по 1.5-3Кб. На практике, чаще растет размер строк, чем их кол-во в файле. Вполне возможно, что я подберу параметры и под миллиард. Миллиард - это много, но у меня такой датасет есть на 65Gb по ~65 символов на строку.

Но я почти смирился с мыслью что при буфере > 2Gb весь выигрыш от seek'ов стремится к нулю и потребуется (N/B)+1 чтений, так что время работы можно оценить на глаз. Моя задача - выяснить, дает ли mmap преимущество, и встроить его в мой алгоритм, если да. Хотя в mmap я не очень верю. И выяснить, в чем и насколько отличаются от нормального шаффла базирующиеся на split эвристики и, если не всплывет ничего ужасного в теории, прикрутить их тоже дополнительным режимом, т.к. на практике многими вещами юзер будет готов пожертвовать. Особенно, если альтернативой будет (N/B)+1 чтений. Но это будет в 16'Q1-Q2. Или если мне самому припрет 500Gb пошаффлить, что не исключено.

Truf
() автор топика
Ответ на: комментарий от Truf

На практике я ограничивался ~15 000 000, но правда, строки были по 1.5-3Кб.

Заранее - я имею в виду общий размер файла. По кол-ву строк я без дополнительных телодвежений и сильных тормозов должен потянуть 200 млн строк + буфером в 1Gb.

Truf
() автор топика
Ответ на: комментарий от Truf

Пока плохо.

я думаю стоит спросить «а есть ли такой готовый алгоритм», а не предлагать свой

что я щас обдумываю:

А. ты даешь программе любую перестановку, лишь бы она помещалась в половину оперативки, и файл

В. программа применяет *именно эту* перестановку к файлу за 1.5 прохода (+ небольшие копейки)

почему 1.5 прохода:

1 проход: читает файл, пишет файлы; 2 проход: читает файлы, пишет результирующий файл в порядке строго от начала к концу, т.е. его можно читать VW-ом через пайп *без записи на диск*

очевидно, что вопрос о несмещенности генератора перестановок тут не стоит :-)

и все-таки мне кажется тебе полезно было бы изучить работу жестких дисков теоретически и практически и написать пейпер, возможно частично под моим руководством? как ты думаешь без этого ворочать файлами в десятки и сотни *тера*байт?

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

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: На mmap от vodz

Я его собрал gcc, запустил с time ./shuf-f -n 46000000 -o ../ml/train.txt_shuffled ../ml/train.txt . Где train.txt - мой приснопамятный файл-пример. Открыл таск менеджер. Выглядит все плохо - он начал аллоцировать Shared Mem до 5.5Gb. Кеш у меня 5.7. RAM usage подскочил до 1 Gb. CPU - 8% от ядра. Когда shared mem дошел до 5Gb он начал писать на диск. CPU упал до disk sleep. Shared Mem стал колебаться от 4.9 до 5.5. По моим ощущениям (на глаз) скорость записи составила 50 Kb\s. Я его остановил - включу на ночь. Если я что-то делаю не так - я открыт для критики.

Да, и я выяснил что на машине, на которой я ставлю эксперименты, нифига не SSD, а HDD Seagate ST1000LM024 в 1Tb. Так что 50Kb\s с оценкой www_linux_org_ru согласуется. Прошу прощение, кого ввел в заблуждение. Простите засранца.

Truf
() автор топика
Ответ на: комментарий от Truf

Так что 50Kb\s с оценкой www_linux_org_ru согласуется.

не пиши бэкслэши, глаз режет, елки-палки

скорость получилась больше чем 20 Кб/с т.к. половина файла (или сколько?) у тебя закэшировалась все-таки

сколько у тебя оперативки?

Если я что-то делаю не так - я открыт для критики.

польза от mmap есть, но она организационно-техническая так сказать, компенсировать плохой алгоритм при недостатке оперативы она конечно же не может

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Truf

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

если скорость у тебя 50 Кб/с вместо 20 Кб/с, а размер файла 10Гб, то оперативы у тебя 6Гб

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от Truf

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

Доказательство там базируется на конкретной методике сортировки. А вот если разрезать исходный файл скажем на m равных частей по n элементов, где m <= n, с остатком k < n элементов, то доказательство не будет действительно. После этого совершаем перестановки — вначале тасуем все m кусков, потом выбираем по случайному числу 0 <= i < m, который есть номер куска, затем берём из этого куска первую строчку, записываем в результирующий файл, пока все куски не кончатся. Как по-твоему, будут ли перестановки n*m равновероятными? Доказательство по ссылке уже не валидно. Кстати понятно откуда оно берётся — если куски были неравными, то в начале файла строки из последнего кусочка, который был длиной только в k элементов в основном попадут в начало результирующего файла, если не сделать вероятность выбора куска пропорциональной его длине.

А вот уже после тасования основной совокупности, оставшийся кусок можно рассовать, просто выбирая случайные позиции в файле.

Xenius ★★★★★
()

Глаз просто радуется глядя на оформление новости: есть и для чего утилита и краткое введение в область применения и почему лучше аналога.

h4tr3d ★★★★★
()
Ответ на: комментарий от pascal

Ну и ботва, теперь я не удивлен выбором qt!

anonymous
()

Для тех кто пытается оптимизировать доступ к диску:

Исходный файл нужно читать последовательно а конечному файлу делать mmap() или pwrite(). Если получится доработать ваши алгоритмы то получите десятки мегабайт в секунду а не десятки килобайт.

cvv ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

У меня 8Gb RAM. Скорость я мерил на глаз, так что она с погрешностью в слона.
Даст ли mmap прирост производительности, если его прикрутить к тому, что реализовано у меня? Т.е. использовать не для рандомного обращения к адресам исходного файла, а для нескольких проходов от его начала к концу с seek'ами? Мне кажется, не должно.

Truf
() автор топика
Ответ на: комментарий от Truf

ПРи последовательном проходе (с пропусками) - не даст

cvv ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

я думаю стоит спросить «а есть ли такой готовый алгоритм», а не предлагать свой

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

А. ты даешь программе любую перестановку, лишь бы она помещалась в половину оперативки, и файл
В. программа применяет *именно эту* перестановку к файлу за 1.5 прохода (+ небольшие копейки)

Я, честно говоря, не понял, как это должно работать. Мы пока умеем генерировать несмещенные перестановки только файла целиком. Если использовать такую - то в кусках, на которые гипотетически распадается исходный файл, должны будут присутствовать строки равновероятно выбранные по всей длине исходного файла. Собрать все эти куски за один проход по исходному файлу можно при записи в рандомную позицию куска на диске. А если по одному - то за множество проходов. Зато можно не сохранять на диск, а сразу писать в результат - это то, что у меня сейчас и сделано. В общем, что-то я тут недопонимаю.

написать пейпер

Боюсь, до конца года у меня не будет времени. Ворочать файлами в десятки терабайт мне предстоит не скоро. Я уже месяцев 7 занимаюсь собственным RnD проектом и, когда устаю, делаю что-нибудь маленькое и полезное. Shuf-t именно так и появился. Но сейчас RnD буксует, а для разминки у меня в очереди пара багфиксов и одна фича в VW. Нужно выдержать эти приоритеты, добавить себе работы я пока не рискну. Даже правки shuf-t я по-возможности отложу на начала сл года.

Truf
() автор топика
Ответ на: комментарий от cvv

Разве это не должно быть медленнее, чем mmap читаемого файла и последовательная запись результата?

Truf
() автор топика

Сколько эту детскую ботву обсуждать? Выше все четко написано, от seek не избавиться, читать в два прохода. Первый проход с mmap, второй без.

anonymous
()
Ответ на: комментарий от Truf

нет. ибо seek() на риде всегда заканчивается сиком головки. А на записи - при необходимости. итого у нас есть возможность дико проредить общее количество сиков.

cvv ★★★★★
()
Ответ на: комментарий от Truf

Я попросил либо готовый алгоритм, либо комменты по предложенному.

на stackoverflow настоятельно просят задавать 1 вопрос в одном посте — мне это раньше не нравилось (2 почти идентичных вопроса со ссылками друг на друга выглядят как-то глупо), но они похоже правы

если готовый алгоритм есть (или если я где-то зверски не ошибся) то комменты по предложенному тобой алгоритму имеют мало ценности, а вот есть ли *готовый* алгоритм — очень даже интересно, чтобы зря велосипед не изобретать

если готового алгоритма нет, то я бы предложил свой

ладно, че у меня вроде выходит:

apply-transpositon -t transposition.bin -i input_30GB.txt | VW

должно работать примерно в 1/3 скорости диска (т.е. около 40МБ/с), занимая если не совру 2ГБ оперативки (т.е. VW остается 6ГБ)

но заниматься самопроверкой, объяснением да обоснованием мне лень, покуда есть шанс, что все давно придумано еще до меня

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 1)
Ответ на: комментарий от Truf

Я, честно говоря, не понял, как это должно работать.

а я и не объяснял, и даже 100% не уверен, что у меня ошибки нет — я трачу на велосипедостроение не слишком много времени

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

«частями». Тесть даже небольшое кеширование даст нам выигрыш как минимум по сикам. А если наши винты сказевые, или в хужем случае умеют NCQ, то тут просто раздолье для оптимизаций сиков кернелом и винтом.

cvv ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Кажется дошло. Проходим по файлу - собираем номера и размеры строк. Потом шаффлим их. Виртуально режем полученное адресное пространство файла результата на куски. Дальше делаем второй проход по файлу - для каждой строки ищем кусок, в который она должна была бы попасть и пишем ее в него на HDD. Итого, после второго прохождения всего файла получим куски содержащие свои строки, но не в том порядке. Т.к. кусок влезает в RAM, берем его в RAM и восстанавливаем зашафленный порядок строк в нем по имеющейся расстановке. Пишем в результат. Берем следующий и т.д. Получится 3 чтения N байт с диска и 2 записи N байт на диск.

Truf
() автор топика
Ответ на: комментарий от cvv

«частями»

большое спасибо, к. о.

очевидно, что меня интересовал (и интересует) вопрос — по какому алгоритму выбирается, что кэшировать, а что выбросить из кэша

А если наши винты сказевые, или в хужем случае умеют NCQ, то тут просто раздолье для оптимизаций сиков кернелом и винтом.

лишний оптимизм

если нам требуется рандомный сик головки винта, то он займет 10мс (ну ладно 5мс у хороших винтов), хоть ты лопни

тут только алгоритм прикладной проги поможет, а не все эти NCQ

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 2)
Ответ на: комментарий от Truf

Получится 3 чтения N байт с диска и 2 записи N байт на диск.

имеем 1/5 скорости диска вместо реализованного тобой в коде 1/(N/B), т.е. 1/10 в случае N=10ГБ, В=1ГБ

но по-моему можно и 1/3, что еще лучше

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

www_linux_org_ru ★★★★★
()
Последнее исправление: www_linux_org_ru (всего исправлений: 2)

Чтобы писать нужно знать что писать, откуда это взять и куда положить. Эта информация доступна только после того как мы знаем сколько строк есть, какие у них смещения и длины. Поэтому на первом этапе последовательно читается файл открытый через mmap. Полученная информация рандомизируется. Запоминается какое было смещение, какое должно быть.

Далее есть два варианта:

1) читать последовательно с mmap, писать с seek.

2) читать с seek, писать последовательно.

первый вариант явно быстрее, поэтому делаем второй проход по входному файлу, читаем последовательно с mmap, просто тупо просматриваем список строк узнаем новое смещение делаем туда seek в выходном файле и записываем туда строку. тупо повторяем пока не кончаться строки. Все.

В памяти никаких буферов не выделяем, сами строки не храним, хреним только старое смещение, новое смещение и длину.

quest ★★★★
()
Последнее исправление: quest (всего исправлений: 3)
Ответ на: комментарий от quest

1) читать последовательно с mmap, писать с seek.
первый вариант явно быстрее

Я пробовал - медленнее. Вначале безусловно скорость впечатляющая, но это обманчиво. Как только кончается кеш и hole становится фрагментированным скорость быстро падает и становится меньше, чем читать с seek с неотключенным read-ahead. К тому же не стоит забывать, что в это режиме результат придётся ждать полностью! Без полного завершения невозможно будет сказать, а не было ли ошибки вообще в алгоритме. При последовательной записи:

a) работа может быть прервана когда надоест ждать

б) вывод можно сделать в stdout/char device

в) от кеширования записи можно отказаться флагом в open, так как то что записали нам больше не нужно и вся память пойдёт на кеширование чтения. В вашем же варианте надо кеш под чтение (ибо двухкратное) и под запись.

vodz ★★★★★
()
Ответ на: комментарий от vodz

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

quest ★★★★
()
Последнее исправление: quest (всего исправлений: 1)
Ответ на: комментарий от quest

Велосипед по оптимизации seek-ов хоть и не rocket-science, вполне продаваемый, те же дефрагментаторы. Иногда приятно размять мозги чем-нибудь...

vodz ★★★★★
()
Ответ на: комментарий от anonymous

Когда в Qt появится своё ядро и система инициализации?

когда systemd перепишут на С++

anonymous
()
Ответ на: комментарий от Truf

На ftp теперь версия с двумя mmap. 30 минут с полным файлом работает. Размер буфера под сборку для записи - опцией. Пишет последовательно, читает последовательно за счёт восстановления порядка после перемешивания qsort-ом. Вроде с O_DIRECT чуть лучше получилось.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Это результат на SSD?
Я попробовал на своем HDD и оригинальном файле. С дефолтным буфером (128 Мб) все было совсем плохо - я его прибил на 28-й минуте и он успел записать чуть больше 8 млн сток из 45.8 млн. Но с буферами 2Gb и 4Gb я получил 17.5 мин и 14 мин соответственно. Похоже, что дальнейшее увеличение буфера выгоды не несет.
Результаты сильно смахивают на benchmark текущего алгоритма: Буфер 1Гб (дефолтный) - 21.37 мин; Буфер 2Гб - 13.55 мин. Что странно. Я shuf-f еще попробую на большем файле (60Gb), чтобы посмотреть, как будет падать производительность. Но в любом случае, не похоже, что бы он был быстрее предложенного алгоритма на split'ах исходного файла. Там, мне кажется, удастся пошафлить 11Gb файл не более чем за 10мин, а www_linux_org_ru считает, что можно и лучше.

Truf
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.