LINUX.ORG.RU
ФорумTalks

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

 , ,


0

4

Привет, ЛОР!

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

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

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

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

★★★★★

Последнее исправление: hobbit (всего исправлений: 1)

Обычно бесплатно ничего не бывает. Делаю ставку на то, что zlib-rs потерял, например, портабельность на другие архитектуры.

pekmop1024 ★★★★★
()

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

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

Обычно бесплатно ничего не бывает.

Ага. Пришлось на Rust писать.

Делаю ставку на то, что zlib-rs потерял, например, портабельность на другие архитектуры.

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

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

Да там как обычно, собственно, такая ситуация буквально во всех раст-проектах:

Our implementation is mostly done, and clearly performs extremely well. However, we’re missing some less commonly used API functions related to gzip files that would make us a complete drop-in replacement in all cases.

Наш вариант быстрее, но там нет половины функционала, но так и оставим.

То же самое происходит буквально во всех попытках заменить сищные утилы растовыми

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

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

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

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

Ичо? Это всё равно получается безопаснее чем писать на Си. Если почитаешь код, там unsafe всего несколько функций.

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

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

Ну и по ссылке как бы

Our implementation is mostly done, and clearly performs extremely well. However, we’re missing some less commonly used API functions related to gzip files that would make us a complete drop-in replacement in all cases.

To complete the work and improve performance and e.g. packaging, we’re seeking funding for the amount of €95.000. See the workplan for details.

Hilbert
()
Последнее исправление: Hilbert (всего исправлений: 1)

если всё это правда, то не раст обогнал, а автор zlib-rs обогнал автора zlib

сишечку нельзя обогнать, с ней можно только сравняться :)

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

Оттуда, что Си – достаточно плохой язык, и оптимизация кода на нём – всратый и неочевидный процесс.

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

зависит от компилятора и от того кто пишет на асме

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

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

всратый и неочевидный процесс

А кто обещал, что будет легко. На асме ещё сложнее.

Если трудно - есть вон питон например :) Ну ладно, пусть будет раст))

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

ну я не спорю, что раст местами вполне сравним с сями

но про «быстрее» - звучит как бред. М быть в llvm оптимизация лучше, если сравнивали с gcc, или кто-то собрал с -O0

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

Если трудно - есть вон питон например :) Ну ладно, пусть будет раст))

Отличная клоунада! Но нет. Вот тебе три примера достаточно банальной функции:

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

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

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

Внимание вопрос: какой из них быстрее и почему это вариант с временной переменной? Есличо, в выхлопе в асме временной переменной скорее всего не будет.

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

Мне кажется, дело не в самом расте, а в тех, кто пытается заменить сишные утилиты :)

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

У компиляторов C большие проблемы с использованием SIMD-инструкций. В общем случае на хорошую компиляцию кода с их использованием рассчитывать не приходится. Поэтому любой хороший видеокодек содержит много кода на ассемблере. Ну и в принципе многие алгоритмы на C можно именно за счёт этого сильно ускорить.

Впрочем Rust от C в этом аспекте не отличается.

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

Это происходит в любых проектах, которые реимплементируют что-то, что существует годами. Язык вообще не при чем.

gaylord
()

почему zlib на Си так плохо оптимизирован?

zlib-rs:

Performance is generally on-par with zlib-ng.

zlib-ng: C11.


The C code is able to use switch implicit fallthroughs to generate very efficient code. Rust does not have an equivalent of this mechanism, and this really slowed us down when data comes in in small chunks.

Nikita Popov suggested we try the -Cllvm-args=-enable-dfa-jump-thread option, which recovers most of the performance here. It performs a kind of jump threading for deterministic finite automata, and our decompression logic matches this pattern.

LLVM does not currently enable this flag by default,…

https://trifectatech.org/blog/zlib-rs-is-faster-than-c/

gag ★★★★★
()

Хехе, сколько они там реализовали от функционала злиба?

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

На 10 000 000 000 итераций разница в пределах погрешности

$ time ./minus
real	0m2.758s
user	0m2.757s
sys	0m0.000s

$ time ./xor
real	0m2.755s
user	0m2.754s
sys	0m0.001s

$ time ./tmp
real	0m2.761s
user	0m2.759s
sys	0m0.001s
sergej ★★★★★
()
Ответ на: комментарий от sergej

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

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

Не знаю, может потому что c aliasing. Компилер не знает, *a содержит все еще то же значение или что-то другие и фетчит его из памяти каждый раз. Но в Си можно указать, что *a не будет меняться. minus_swap(restric *a, …). Как-то так.

Скептически смотрю на раст, т.к. не уверен что он может быть первым яп. Т.е. сразу нужно начить с боундс чекера… когда будет опыт преподавания раст в школах, тогда будет виднее. ИМО важнее, чтоб яп был простым.

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

Rust нормально преподавать после C. Причём в идеале дать на C какой-нибудь не крошечный проект, где проблема времени жизни объектов стоит вовсю, чтобы человек помучился хорошенько, и может даже начал в голове у себя какие-то правила владения сам придумывать. И вот на эту почву Rust ляжет как родной.

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

Не знаю, может потому что c aliasing. Компилер не знает, *a содержит все еще то же значение или что-то другие и фетчит его из памяти каждый раз. Но в Си можно указать, что *a не будет меняться. minus_swap(restric *a, …). Как-то так.

Всё проще, анон. В первом варианте переменные просто загружаются в разные регистры, а потом сгружаются обратно, но адреса поменяны местами.

А ещё в варианте с минусом потенциальное переполнение, и от этого сишным компилятором рвёт жопу. А потом сишникам, ибо UB.

Скептически смотрю на раст, т.к. не уверен что он может быть первым яп.

Так и есть. Только Си им тоже быть не может. Люди, у которых си – первый язык, вырастают лютыми говнокодерами.

ИМО важнее, чтоб яп был простым.

Си не является простым языком. Даже близко.

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

это и было с -O2 он довольно хорошо сообразил что я хотел и выкинул все эти функции

А вот с -O0 начинается дичь с call tmp_swap и работает примерно в 30 раз медленнее

Код от O2 совпадает:

$ grep -B13 'jne' *.s
minus.s-	movabsq	$10000000000, %rax
minus.s-	movl	$432, %ecx
minus.s-	movl	$123, %edx
minus.s-	jmp	.L6
minus.s-	.p2align 4
minus.s-	.p2align 4,,10
minus.s-	.p2align 3
minus.s-.L7:
minus.s-	movl	%edx, %esi
minus.s-	movl	%ecx, %edx
minus.s-	movl	%esi, %ecx
minus.s-.L6:
minus.s-	subq	$1, %rax
minus.s:	jne	.L7
--
tmp.s-	movabsq	$10000000000, %rax
tmp.s-	movl	$432, %ecx
tmp.s-	movl	$123, %edx
tmp.s-	jmp	.L6
tmp.s-	.p2align 4
tmp.s-	.p2align 4,,10
tmp.s-	.p2align 3
tmp.s-.L7:
tmp.s-	movl	%edx, %esi
tmp.s-	movl	%ecx, %edx
tmp.s-	movl	%esi, %ecx
tmp.s-.L6:
tmp.s-	subq	$1, %rax
tmp.s:	jne	.L7
--
xor.s-	movabsq	$10000000000, %rax
xor.s-	movl	$432, %ecx
xor.s-	movl	$123, %edx
xor.s-	jmp	.L6
xor.s-	.p2align 4
xor.s-	.p2align 4,,10
xor.s-	.p2align 3
xor.s-.L7:
xor.s-	movl	%edx, %esi
xor.s-	movl	%ecx, %edx
xor.s-	movl	%esi, %ecx
xor.s-.L6:
xor.s-	subq	$1, %rax
xor.s:	jne	.L7
sergej ★★★★★
()
Ответ на: комментарий от sergej

сишечку нельзя обогнать, с ней можно только сравняться

ага «верую ибо абсурдно», хоть сектанские мантры доказательств не требуют, но всё-таки хоть какое-то логическое обоснование за этим стоит? сишечка же как-будто специально слеплена для того чтобы максимально мешать компилятору её оптимизировать

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

ассемблерный и сишный код выше - зацени до чего дошел прогресс

максимально мешать компилятору

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

представляю какой это ад делать компиляторы

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

а что я должен был измерить? с -O0 что ли?

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

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

а ничо. просто засуньте себе ваши победы в то самое место, откуда растишечка растет.

Поздно. Rust уже в ядре. И дистры его собирают туда.

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

а главное он сообразил, что swap это swap и сделал 3 команды movl из всех 3х функций

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

а что я должен был измерить? с -O0 что ли?

Вынести функции в отдельную сошку и запускать бенч с вызовом её ты не додумался? Ну чтобы компилятор не выкидывал их.

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

Ага. Ты измерил херню и гордишься этим. Типичный сишник.

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

это ты вместо теста запостил херню :)

или в твоем понимании оптимизатор - это не си и его надо принципиально отключать?

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

Мякотку-то, самую мякотку забыл:

To complete the work and improve performance and e.g. packaging, we’re seeking funding for the amount of €95.000

:) :) :)

Цыгане хреновы. :)

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

Поздно. Rust уже в ядре. И дистры его собирают туда.

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

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

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

Погоди, так вроде C – low level и должен отражать железо. Как же так вышло?

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

€95.000

тыщ фунтов стерлингов? лучше отдать пенсионерам!

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

C – low level и должен отражать железо

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

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

выжал все возможные ключи оптимизации

–release?

компилировался полтора часа

не видел ни одну программу на расте чтобы она более получаса компилировалась. в отличие от

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

кому должен?

Программистам. Иначе зачем он вообще нужен такой?

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

Т.е. он низкоуровневый (близкий к железу) и одновременно не низкоуроневый (далекой от современных CPU)? Как это возможно-то?

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

В моём понимании, у меня с -O2 получилось 1.77s на tmp_swap, 2.57s на xor_swap и 2.56s на minus_swap. По 1024^3 итераций везде.

То, что ты не осилил такой простой бенч сделать сам и при этом имеешь мнение, является очень забавным. Серьёзно.

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

Иначе зачем он вообще нужен такой?

Чтоб писать низкоуровневые вещи. Все живые ядра осей написаны на нём. В будущем может это измениться, но пока альтернатив нет.

низкоуровневый (близкий к железу) и одновременно не низкоуроневый

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

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