February 18th, 2020

Book

LZ4 на винде

Я тут тестирую LZ4 и ZSTD путём запаковывания 40 гб текстового говна на сетевую шару на QNAP.

Собственно это два архиватора у которых вменяемый процесс релизов и есть бинарники под винду. Ну то есть не просто "текущая версия хуеты", а какой-то шанс что пакуемое потом удастся распаковать.

По шаре льётся на ~300 мбит/сек, немного медленновато, но больше 100 и хуй с ним.

Так вот, на 8-ядерной тачке lz4.exe -3 демонстрирует чудеса: 9% цпу, 30 метров чтение с диска 10 метров запись в сеть.

Вопрос: где боттлнек, товарищи? Как может быть без боттлнека? Скажем 12% цпу, 80 метров чтения с диска и 30 метров записи в сеть это примерные боттлнеки.

По моему опыту такая хуета происходит, если IO сделан через жопу. Например буфер уменьшился и всё пизда производительности. Я тут даже подумал, что может хардвари пизда настала от бенчмарков, но нет - lz4 -1 читает все 80.

У zstd тоже не всё в порядке. zstd -1 работает крайне медленно. Упирается в проц, хотя по агиткам должен упираться в диск. Может конечно это датасет ему не подходит, но вряд ли до такой степени. Скорее всё тот же IO.

В-общем даёшь нормальный ввод-вывод архиваторам!

Upd: дисковый боттлнек аж 160 MB/сек если его правильно готовить, там raid1 c 2 SAS-винтами. Любители попиздеть про SSD идут лесом - с SSD просто неправильно приготовленный IO быстрее, а разница между правильным и неправильным ~8x. Ну то есть на SSD убожество IO было бы только более заметно.
Book

Чистый Си в 2020

INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
  if (loop->pending_reqs_tail) {
    req->next_req = loop->pending_reqs_tail->next_req;
    loop->pending_reqs_tail->next_req = req;
    loop->pending_reqs_tail = req;
  } else {
    req->next_req = req;
    loop->pending_reqs_tail = req;
  }
}
По-моему, любить писать такой код каждый раз - это особого рода болезнь головы. Это похоже на FIFO-очередь на интрузивном однонаправленном списке со вставкой в хвост, но на самом деле кольцо. Дополнительные очки спецолимпиады заработали за:

- борьбу с инлайнером в 2020
- оставленные внутри ветвления (по недосмотру или с целью "читаемости") одинаковые куски
- рябь в глазах от loop->pending_reqs_tail (зато "явность", и отсутствие указателей на указатели, чо)

Зато IOCP используют. Но там тоже хез, если использовать в своём приложении - то надо аккуратно следить за тем, есть ли разница от флагов. Они, например, всё открывают с backup semantics и share_read, просто из-за какой-то юниксоидной шизы. В любом случае понятно, что абстракция течёт, конечно.

Интересно в этом плане посмотреть на windows only IOCP event loop, с полным контролем флагов, на нормальном языке (С++17, Rust, TS), c промисами, блекджеком и шлюхами.