Даже если (вдруг, внезапно) бранч-предиктор адаптируется на 9 знаков, то для любой другой длины (а она случайна) он ошибётся.
С пробелами ошибок будет меньше, ибо в большинстве случаев они будут одиночными. Однако, будут и не одиночные проблемные символы, в то время как в исходном тестовом наборе они всегда одиночные (и предиктор действительно будет это угадывать).
Да, статья о libmdbx планируется в ближайшее время (как и статьи о libfptu, libfpta, реализации double-to-string по готовности планируемых доработок). Всё это по мере наличия времени и желания, без обязательств.
MDBX является развитием LMDB. Информация об этом есть в README вместе со списком отличий/доработок. В свою очередь по LMDB в Сети есть масса информации. Должны быть доступны записи моих докладов на Highload++ (но там очень плохой звук).
На остальные ваши вопросы нет простых ответов, которые можно было-бы дать в два часа ночи в подобном комментарии.
AVX, SSE и прочие фигня всё это в данном случае. Есть еще другие способы оптимизации:
Ой не говорите, ерундой какой-то занимаемся.
файл большой => следует читать асинхронно, пока читает обрабатывать прочитанное. Задача проста: обработать данные до получения следующего блока.
Видимо не в теме этой прорывной технологии. Поэтому просто разместили файл в tmpfs чтобы было меньше букв в коде.
для обработки выбрать блоки которые целиком помещаются в кэш. Это даст прирост больший чем векторные инструкции ожидающие готовности памяти.
Это даст прирост если данные читаются больше одного раза, а в здешнем баловстве это не так. Поэтому хватает prefetch. Более того, в подобных практических задачах всегда выгоднее не засорять кэш данными читаемыми однократно. Т.е. буквально для AVX2 будет выгоднее делать предвыборку вручную в потоковом режиме, обрабатывания данные кэш-линияим (по 64 байта).
приводить результаты в абсолютных величинах Gb/s и сравнивать с максимальной пропускной способностью в %. Например по отношению к HDD 160Mb/s, SSD 500Mb/s… 4Gb/s, RAM 40-80Gb/s
В этом есть здравое зерно, но нет рациональности. Поскольку варианты кода сравнивались между собой на одной машине по wall clock, и намеренно без дискового обмена.
В целом — спасибо, посмешили.
Всё-же желательно читать статьи перед тем так блистать в комментариях.
Может-может, и VirtualAllocEx() из другого процесса… Т.е. конечно это все костыли.
В libmdbx гонки с новыми тредами обходятся захватом SlimRwLock в специфических местах. А для общего случая нужно мешать хук на создание тредов, с локом внутри.
С другой стороны, в худшем случае адреса окажутся заняты.
Не считая перехода на linux решение примерно одно: suspend-ить все треды (кроме текущего) перед VirtualFree() и resume-ть после окончания манипуляций. Работающую реализацию можно подсмотреть у меня в libmdbx (используется для ремапинга), ибо есть нюансы.
То что qrck13 пишет о MapViewOfFile() иногда происходит из-за антивирусов (пытаются заглянуть в эти замепленные файлы).
Скорость хаскель-кода зависит только от средней длины слов, а картина распределения как и длина не играет роли (с поправкой что слово не может быть длиннее строки). Видимо это не очевидно и (соответственно) должно быть явно разъяснено в статье. Поэтому я намерено ушел от поиска "идеального" текста в качестве тестовых данных. По той же причине оба замечания беспочвенны.
Использование данных /dev/urandom абсолютно оправдано и неплохо иллюстрирует недостаток хаскель-кода, тогда как первоначальные данные этот недостаток маскируют — это главное. Случайные данные не являются идеальным тестовым набором, но использование "идеального текста" (какой он и почему именно такой?) будет скорее перфекционизмом.
TL;DR с системной утилитой wc нет смысла соревноваться — лежачего не бьют. Но на самом деле wc учитывает юникодные варианты пробелов и подсчитывает печатную дли строк (с табуляциями и вот это вот всё). Остальное подробности в комментариях к первой статье.
Вы что-то совсем не верно поняли, возможно мне стоит переформулировать текст или сместить акценты (но пока лень).
Код сгенерированный ghc в принципе не оптимальный, но показывает хорошие результаты только на сильно смещенных данных. Он особенно хорош если в гигабайтном тексте будет одно слово. Поэтому хаскель-коду буквально сильно повезло с тестовыми данными в первой статье.
Далее, случайные данные с точки зрения ТЗ являются не мусором, а совершенно корректными данными с более естественными статистическими показателями. Данные из /dev/urandom взять было просто удобнее, но если взять любой текст то результат будет примерно аналогичным. Пожалуйста попробуйте и отпишите, если сомневаетесь.
Никто не собирался делать это переносимым дальше POSIX и загромождать исходный код. Под "переносимостью" прежде всего подразумевалась отсутствие привязи к x86 (особенно всяческие SIMD).
mmap() ничего не меняет, но остался по историческим причинам. Если аккуратно закомментировать, то всё должно работать (хотя я уже не помню проверял или нет).
В windows есть CreateFileMapping() и MapViewOfFile(). Поправить элементарно, либо WSL.
Если не затруднит, то прогоните пожалуйста на вашей машине вариант с развернутым циклом (т.е. с заменой этого цикла на код под спойлером). Хочется нащупать отличие кода из-под ghc от C.
FSM в наивной реализации будет в разы медленнее показанной наивной реализации на C. Но если продолжить вашу мысль в верном направлении, то получится что-то подобное.
Кстати, ассемблерный вывод ghc совсем сухой, без его "технических" комментариев?
Может какой-нибудь ключик есть для аннотации?
Должны быть какие-то средства навигации или "дорожные столбы", чтобы сами разработчики ghc поманили что из чего получилось.
Вот интересно, какова логика минусующих?
Даже если (вдруг, внезапно) бранч-предиктор адаптируется на 9 знаков, то для любой другой длины (а она случайна) он ошибётся.
С пробелами ошибок будет меньше, ибо в большинстве случаев они будут одиночными. Однако, будут и не одиночные проблемные символы, в то время как в исходном тестовом наборе они всегда одиночные (и предиктор действительно будет это угадывать).
На всякий — все результаты и выводы подтвердились для ghc 8.8.3, LLVM-бакендом и на текстах Шекспира.
См под спойлером в конце статьи.
Все результаты и выводы подтвердились для ghc 8.8.3, LLVM-бакендом и на текстах Шекспира.
См под спойлером в конце статьи.
// промазал
Спасибо за отзыв!
Да, статья о libmdbx планируется в ближайшее время (как и статьи о libfptu, libfpta, реализации double-to-string по готовности планируемых доработок). Всё это по мере наличия времени и желания, без обязательств.
MDBX является развитием LMDB. Информация об этом есть в README вместе со списком отличий/доработок. В свою очередь по LMDB в Сети есть масса информации. Должны быть доступны записи моих докладов на Highload++ (но там очень плохой звук).
На остальные ваши вопросы нет простых ответов, которые можно было-бы дать в два часа ночи в подобном комментарии.
Либо прочитайте все четыре статьи, либо ложитесь спать.
Вы несете чушь, потому что 9 знаков — это среднее значение случайной величины.
Ой не говорите, ерундой какой-то занимаемся.
Видимо не в теме этой прорывной технологии. Поэтому просто разместили файл в tmpfs чтобы было меньше букв в коде.
Это даст прирост если данные читаются больше одного раза, а в здешнем баловстве это не так. Поэтому хватает prefetch. Более того, в подобных практических задачах всегда выгоднее не засорять кэш данными читаемыми однократно. Т.е. буквально для AVX2 будет выгоднее делать предвыборку вручную в потоковом режиме, обрабатывания данные кэш-линияим (по 64 байта).
В этом есть здравое зерно, но нет рациональности. Поскольку варианты кода сравнивались между собой на одной машине по wall clock, и намеренно без дискового обмена.
В целом — спасибо, посмешили.
Всё-же желательно читать статьи перед тем так блистать в комментариях.
Может-может, и VirtualAllocEx() из другого процесса… Т.е. конечно это все костыли.
В libmdbx гонки с новыми тредами обходятся захватом SlimRwLock в специфических местах. А для общего случая нужно мешать хук на создание тредов, с локом внутри.
С другой стороны, в худшем случае адреса окажутся заняты.
Не считая перехода на linux решение примерно одно: suspend-ить все треды (кроме текущего) перед
VirtualFree()
и resume-ть после окончания манипуляций. Работающую реализацию можно подсмотреть у меня в libmdbx (используется для ремапинга), ибо есть нюансы.То что qrck13 пишет о
MapViewOfFile()
иногда происходит из-за антивирусов (пытаются заглянуть в эти замепленные файлы).Скорость хаскель-кода зависит только от средней длины слов, а картина распределения как и длина не играет роли (с поправкой что слово не может быть длиннее строки). Видимо это не очевидно и (соответственно) должно быть явно разъяснено в статье. Поэтому я намерено ушел от поиска "идеального" текста в качестве тестовых данных. По той же причине оба замечания беспочвенны.
Использование данных
/dev/urandom
абсолютно оправдано и неплохо иллюстрирует недостаток хаскель-кода, тогда как первоначальные данные этот недостаток маскируют — это главное. Случайные данные не являются идеальным тестовым набором, но использование "идеального текста" (какой он и почему именно такой?) будет скорее перфекционизмом.В статье есть упоминание про
/dev/shm
, это tmpfs. Видимо авто предыдущего комментария заметил это и удалил свое примечание.Вероятно у меня будет время чтобы добавить результаты от более новых компиляторов из Fedora 31 на чуть более современно процессоре.
TL;DR с системной утилитой
wc
нет смысла соревноваться — лежачего не бьют. Но на самом делеwc
учитывает юникодные варианты пробелов и подсчитывает печатную дли строк (с табуляциями и вот это вот всё). Остальное подробности в комментариях к первой статье.В POSIX есть
madvise()
, а в windows некоторые костыли.Но к теме статьи это отношения примерно не имеет.
Вы что-то совсем не верно поняли, возможно мне стоит переформулировать текст или сместить акценты (но пока лень).
Код сгенерированный ghc в принципе не оптимальный, но показывает хорошие результаты только на сильно смещенных данных. Он особенно хорош если в гигабайтном тексте будет одно слово. Поэтому хаскель-коду буквально сильно повезло с тестовыми данными в первой статье.
Далее, случайные данные с точки зрения ТЗ являются не мусором, а совершенно корректными данными с более естественными статистическими показателями. Данные из /dev/urandom взять было просто удобнее, но если взять любой текст то результат будет примерно аналогичным. Пожалуйста попробуйте и отпишите, если сомневаетесь.
mmap()
ничего не меняет, но остался по историческим причинам. Если аккуратно закомментировать, то всё должно работать (хотя я уже не помню проверял или нет).Если не затруднит, то прогоните пожалуйста на вашей машине вариант с развернутым циклом (т.е. с заменой этого цикла на код под спойлером). Хочется нащупать отличие кода из-под
ghc
отC
.FSM в наивной реализации будет в разы медленнее показанной наивной реализации на C. Но если продолжить вашу мысль в верном направлении, то получится что-то подобное.
Кстати, ассемблерный вывод
ghc
совсем сухой, без его "технических" комментариев?Может какой-нибудь ключик есть для аннотации?
Должны быть какие-то средства навигации или "дорожные столбы", чтобы сами разработчики ghc поманили что из чего получилось.