LINUX.ORG.RU
ФорумTalks

Rust обогнал Сишечку по скорости распаковки

 , ,


0

5

Привет, ЛОР!

Случилось непредвиденное и невероятное: реализация библиотеки zlib на Rust (zlib-rs) обогнала реализацию на C по скорости распаковки и показывает примерно схожую с последней скорость запаковки данных. Разница в производительности может достигать аж 14%.

Есть ли смысл теперь вообще писать новый софт на Си, если даже в производительности он начинает терять лидерство? Что скажут эксперты по Си и почему zlib на Си так плохо оптимизирован?

Ссылка на бенчмарки: https://trifectatech.org/blog/zlib-rs-is-faster-than-c/

Перемещено dataman из development

★★★★★

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

Получается плохой генератор случайных чисел:

$ cat tb.c
#include <x86intrin.h>
#include <stdint.h>
#include <stdio.h>
#ifdef NOINLINE
#define ATTR __attribute__ ((noinline))
#else
#define ATTR
#endif

void ATTR tmp_swap(volatile int *a, volatile int *b)
{
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

void ATTR xor_swap(volatile int *a, volatile int *b)
{
	*a ^= *b;
	*b ^= *a;
	*a ^= *b;
}

void ATTR minus_swap(volatile int *a, volatile int *b)
{
	*a = *a + *b;
	*b = *a - *b;
	*a = *a - *b;
}


int main(void)
{
	volatile int a = 1, b = 2;
        uint64_t t0, t1, t2, t3;

        t0 = _rdtsc();
        minus_swap(&a, &b);
        t1 = _rdtsc();
        xor_swap(&a, &b);
        t2 = _rdtsc();
        tmp_swap(&a, &b);
        t3 = _rdtsc();
        printf("minus:  %20ld\n", t1-t0);
        printf("xor:    %20ld\n", t2-t1);
        printf("tmp:    %20ld\n", t3-t2);

        return 0;
}
$ gcc -O3  tb.c 
$ ./a.out 
minus:                   205
xor:                      95
tmp:                      35
$ gcc -O3  tb.c -DNOINLINE
$ ./a.out 
minus:                   400
xor:                     125
tmp:                     138
$ ./a.out 
minus:                   375
xor:                     125
tmp:                     137
$ ./a.out 
minus:                   375
xor:                     125
tmp:                     137
luke ★★★★★
()
Ответ на: комментарий от firkax

Включая 16-битные, включая pre-C89 (K&R) компиляторы итд.

На Macintosh Programmers Workbench тоже запустится?

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

«Зло не может создать ничего нового, оно может только испортить и разрушить то, что изобрели или создали добрые силы»,

— Дж. Р. Р. Толкин

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

Ну им же надо чем-то платить всем вот этим агитаторам из Rust Evangelism Strike Force.

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

фортран обгоняет си в математике да и больше могёт, и ближе по синтаксису к ассемблеру сопроцессора.

s-warus ★★★
()

Я правильно понимаю, что эти милые люди сравнивают код на ржавом:

  • скомпиленный со всеми вовзможными флагами оптимизации, которые только смогли подобрать авторы, не угробив экзешник;
  • слинкованный статически;
  • с использованием горячего кода SIMD, выбранного под конкретный процессор во время компиляции и слинкованного так же статически;

с кодом на Си, взятым из zlib-ng, который:

  • был собран без оптимизации, пока авторы высера не доказали обратное;
  • был слинкован динамически (т.е. вызов происходит медленнее, чем при статической линковке);
  • который выбирает используемые функции SIMD в рантайме (что вносит дополнительные тормоза);
  • который вызывает код SIMD не напрямую, а через указатели, либо свичи (тормоза++);
  • и который любом случае чуть более чем в два раза медленнее своего прямого аналога из libdeflate;

получают при этом +16% производительности в сторону ржавого и на этом основании объявляют блескучу перемоху???

А ты говоришь, что ржавый уделал няшную по производительности???

Ёмаё, ну толсто же!

Эта ваша zlib-rs мало того, что недоделанная, так она ещё и медленнее libdeflate раза в полтора!

Я был о тебе лучшего мнения, чувак…

shkolnick-kun ★★★★★
()
Ответ на: комментарий от gaylord

Сишка медленнее ассемблера

Всё что нужно знать о квалификации растяп.

no-such-file ★★★★★
()
Ответ на: комментарий от vbr

Поэтому любой хороший видеокодек содержит много кода на ассемблере

На интринсиках, а не на ассемблере. И нет у Си никаких с этим проблем.

no-such-file ★★★★★
()
Ответ на: комментарий от hateyoufeel

Так если компилятор раста требует указания дополнительной по сравнению с си информации и на основании это информации генерирует более эффективный код, то за что они деньги просят? Оно по дефолту должно быстрее работать

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

Они никого не обманывают

Допустим, они умалчивают…

no-such-file ★★★★★
()
Ответ на: комментарий от shkolnick-kun

с кодом на Си, взятым из zlib-ng, который:

любом случае чуть более чем в два раза медленнее своего прямого аналога из libdeflate;

Так как поддержку zlib-ng в lzbench добавил я, то считаю своим долгом :) уточнить, что на данный момент в lzbench используются не оптимизированные функции zlib-ng, а их generic-аналоги. Вот кусочек из Makefile:

ifeq "$(DONT_BUILD_ZLIB_NG)" "1"
    DEFINES += -DBENCH_REMOVE_ZLIB_NG
else
    ZLIB_NG_FILES  = lz/zlib-ng/adler32.o lz/zlib-ng/crc32.o lz/zlib-ng/deflate_medium.o lz/zlib-ng/deflate_stored.o lz/zlib-ng/inftrees.o lz/zlib-ng/uncompr.o
    ZLIB_NG_FILES += lz/zlib-ng/compress.o lz/zlib-ng/deflate.o lz/zlib-ng/deflate_quick.o lz/zlib-ng/functable.o lz/zlib-ng/insert_string.o lz/zlib-ng/zutil.o
    ZLIB_NG_FILES += lz/zlib-ng/cpu_features.o lz/zlib-ng/deflate_fast.o lz/zlib-ng/deflate_rle.o lz/zlib-ng/infback.o lz/zlib-ng/insert_string_roll.o
    ZLIB_NG_FILES += lz/zlib-ng/crc32_braid_comb.o lz/zlib-ng/deflate_huff.o lz/zlib-ng/deflate_slow.o lz/zlib-ng/inflate.o lz/zlib-ng/trees.o

    ZLIB_NG_FILES += lz/zlib-ng/arch/generic/adler32_c.o lz/zlib-ng/arch/generic/chunkset_c.o lz/zlib-ng/arch/generic/crc32_braid_c.o lz/zlib-ng/arch/generic/slide_hash_c.o
    ZLIB_NG_FILES += lz/zlib-ng/arch/generic/adler32_fold_c.o lz/zlib-ng/arch/generic/compare256_c.o lz/zlib-ng/arch/generic/crc32_fold_c.o

#    ZLIB_NG_FILES += lz/zlib-ng/arch/x86/adler32_avx2.o lz/zlib-ng/arch/x86/adler32_ssse3.o lz/zlib-ng/arch/x86/chunkset_ssse3.o lz/zlib-ng/arch/x86/crc32_vpclmulqdq.o
#    ZLIB_NG_FILES += lz/zlib-ng/arch/x86/adler32_avx512.o lz/zlib-ng/arch/x86/chunkset_avx2.o lz/zlib-ng/arch/x86/compare256_avx2.o lz/zlib-ng/arch/x86/slide_hash_avx2.o
#    ZLIB_NG_FILES += lz/zlib-ng/arch/x86/adler32_avx512_vnni.o lz/zlib-ng/arch/x86/chunkset_avx512.o lz/zlib-ng/arch/x86/compare256_sse2.o lz/zlib-ng/arch/x86/slide_hash_sse2.o
#    ZLIB_NG_FILES += lz/zlib-ng/arch/x86/adler32_sse42.o lz/zlib-ng/arch/x86/chunkset_sse2.o lz/zlib-ng/arch/x86/crc32_pclmulqdq.o lz/zlib-ng/arch/x86/x86_features.o
endif
dataman ★★★★★
()
Ответ на: комментарий от hateyoufeel

Ну для OoO не так важно, это верно.

luke ★★★★★
()
Ответ на: комментарий от shkolnick-kun

Буквально, да, все так. Причём с этим носятся на серьёзных щщах.

Obezyan
()

Я предлагаю разделять высмеивание растофанбоев и обсуждения недостатков раста. У каждого языка есть свои сильные и слабые стороны, а у растофанбоев - пока только слабые :)

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

У каждого языка есть свои сильные и слабые стороны, а у растофанбоев - пока только слабые :)

Проблема в том, что на ЛОРе нет ярых фанатов раста. Иначе я бы им тоже повбрасывал.

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

Проблема в том, что на ЛОРе нет ярых фанатов раста. Иначе я бы им тоже повбрасывал.

Ну, гейлорд пытался гнуть пальцы на эту тему, но ему быстро их сломали. Других пока не наблюдается, к сожалению.

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

Obezyan
()
Ответ на: комментарий от luke

А есть пример где фортран рулит? Что-нибудь со степенями и комплексными числами?

Например, Native Fortran Implementation of TensorFlow-Trained Deep and Bayesian Neural Networks ©.

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

Ну, гейлорд пытался гнуть пальцы на эту тему, но ему быстро их сломали. Других пока не наблюдается, к сожалению.

Не уверен, что обломали, но на фаната раста он даже близко не похож.

Трагедия ЛОРа в том, что население стареет: средний возраст ЛОРовцев – под 40. Ясен хрен тут никто ничего нового не осиливает.

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

Не уверен, что обломали, но на фаната раста он даже близко не похож.

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

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

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

Ты эксперт по геям, что ли?

hateyoufeel ★★★★★
() автор топика

Ничёсе они там денег собрали на переписывание всего на раст. Я тоже хочу такой фигней страдать за деньги.

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

Спасибо что время сэкономил, ясно что чудес не бывает, но я сразу не нашёл. Правда, справедливости ради, libdeflate никто не использует, на практике везде всё завязано на zlib API/ABI.

Интересно есть ли хотя бы смысл в плане безопасности, или у них там на hot path тот же unsafe натыкан ради производительности.

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

Я недавно узнал, что в rust нет возможности словить float-исключение (как fenv.h), типа если у тебя код делает полторы тысячи формул и в сях ты просто в конце чекаешь состояние флагов FE_DIVBYZERO/FE_INVALID/FE_OVERFLOW/FE_UNDERFLOW и если хотя бы один взведен - то дропаешь результат математики и ждешь следующей итерации (например удобно для потоковой обработки данных с измерительного оборудования).

В Rust предлагается на каждый float делать isnan/isinfinity etc.

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

Ты эксперт по геям, что ли?

а где я про них говорил???

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

Но без Эдика всё-равно как-то скучно.

luke ★★★★★
()

Всё конечно хорошо и верно, но морковка не купился на этот раз.

XMPP
()
Ответ на: комментарий от Avial

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

bdrbt
()
Ответ на: комментарий от hateyoufeel

Все эти mut, указания владения это же дополнительная информация по сравнению с кодом на си? Компилятор раста без нее не соберёт программу? Значит компилятор требует этой информации?

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

Все эти mut, указания владения это же дополнительная информация по сравнению с кодом на си?

Я даже не знаю, как это прокомментировать. Это настолько тупо, что я просто поражён!

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

С ходу нифига не находится.

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

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

Подтверждаю. Интегрировал в один сервис эту штуку - огонь, скорость генерации увеличило примерно в 1000 раз. Там растеризация была из SVG в PNG. Потом, правда, вообще всё переписал на JavaScript и увеличил ещё в 100 раз, но это уже другая история.

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

А что есть проще C?

Какие-нибудь Nim или Zig. Если взять подмножество Rust без borrow checker и лайфтаймов, оно тоже будет проще.

В Си просто вагон правил по семантике вокруг указателей, модели памяти и прочих крайне неочевидных штук. Сделать совместимую со стандартом реализацию Си – достаточно сложная задача. Смотри выше по треду мою переписку с sjinks про restrict. И это только вершина айсберга всей этой безумно душной сишной хреноты.

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

Сделать совместимую со стандартом реализацию Си – достаточно сложная задача

Сделать оптимизирующий компилятор - достаточно сложная задача. А так: каждый доступ к memory location компилируем в соответствующую(ие) инструкции процессора, restrict игнорируем, определяем __STDC_NO_ATOMICS__ и забиваем на них.

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

И получаем сломанный код. Браво!

Не-а.

The intended use of the restrict qualifier (like the register storage class) is to promote optimization, and deleting all instances of the qualifier from all preprocessing translation units composing a conforming program does not change its meaning (i.e., observable behavior).

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

утверждение про обгон сишечки - это примерно как язык X обогнал ассемблер

Неоднократно читал про обгон ассемблера на Форте :)

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

Не-а.

Да-а. Смотри выше пример как restrict меняет поведение функции.

a conforming program does not change its meaning (i.e., observable behavior).

Ключевой термин «conforming program». Половина сишного кода поражена UB.

Один хрен restrict даже не самое стрёмное тут. Strict aliasing хуже.

hateyoufeel ★★★★★
() автор топика
Последнее исправление: hateyoufeel (всего исправлений: 1)
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)