Во фронтэнде компилятора Rust, выполняющем такие задачи, как синтаксический анализ, проверка типов и анализ заимствований, реализована поддержка параллельного выполнения, позволяющего существенно сократить время компиляции. Распараллеливание уже доступно в ночных сборках Rust и включается при помощи опции "-Z threads=8". В стабильную ветку рассматриваемую возможность планируют включить в 2024 году...Подробнее: https://www.opennet.dev/opennews/art.shtml?num=60095
это получается я смогу быстрее компилять фаерфокс?
Там у огнелисы лишь небольшие куски на расте, поэтому даже медленнее получиться.
Стоит запустить cloc перед тем как комментировать
Ты запустил сам-то? Какие результаты? ff на с++ и js написан - шах и мат.
Санта-Барбара "онаним газифицирует лужу" серия 1337
https://openhub.net/p/firefox/analyses/latest/languages_summary
ого, это получается что в следующем (возможно в 25м) году Раст обгонит Сишку
Неплохо, весьма неплохо!
Последние пару лет Раст и Сишка соревновались только в том кого из них первым выкинут из проекта.
Б-же, 4 ляма строк на HTML, даже больше, чем на С. И после этого некоторые продолжают утверждать, что HTML не язык программирования, а я не могу являться сертифицированным HTML-программистом.А если серьёзно, откуда так много? Весь интерфейс лисы описан на html/js?
«Вы говорите что HTML невозможно программировать. По-моему вы просто жутко наелись конфет…» — Денис Попов
> А если серьёзно, откуда так много? Весь интерфейс лисы описан на html/js?Да. XUL мёртв, но подходы его живы.
Хотя я уверен, что до половины от этого занимает монструозный about:newtab с нескучными списками самых посещаемых сайтов на react.js.
> Весь интерфейс лисы описан на html/js?Было бы прекрасно, если все интерфейсы писались на стеке html/css/js.
> А если серьёзно, откуда так много? Весь интерфейс лисы описан на html/js?Не только интерфейс, но и многая внутренняя логика. Чего удивительного? Ты посмотри сколько занимает в процентном соотношении код на lua или vimscript в neovim, или код на elisp в emacs.
Зачем там BrainFuck?
Чтоб тебе стало инетресно и ты сломал мозг))
Очевидно это некорректные данные от систем, которые определяют тип файла.
11% - это много? Потом идет python, будет говорить что ff на питоне? Или ты сразу встал в защитную позу из-за того, что кто-то сказал что тебе не нравится?
Учитывая, что код на Python форматирован без скобок и в целом более компактный и высокоуровневый, можно смело говорить, что Firefox скорее написан на Python, чем на Rust. Не говоря уже о Javascript.
Ну а как вы хотели?
Остаётся этот самый бекэнд на Раст переписать. Зиг по слухам уже слезает с ллвмной иглы.
Совсем не по слухам, давно стоит чёткая цель
Не очень понятно 'зачем'?
Т.е можно потратить N сотен человеко-часов, а можно за это время и силы добавить какие-то полезные конструкции в язык или оптимизировать быстродействие.Даже в упомянутом тикете Зиг мотивация довольно размытая:
- All our bugs are belong to us.
Ну так вам их все и чинить придется) А над ЛЛВМ работает еще куча людей.- The Zig compiler binary goes from about 150 MiB to 5 MiB.
Думаю речь про дебажные билды, да и 150 не такое большое число.- We can implement our own optimization passes that push the state of the art of computing forward.
Спасибо, мы уже насмотрелись на оптимизации в С/С++- We can attract direct contributions from Intel, ARM, RISC-V chip manufacturers, etc., who have a vested interest in making our machine code better on their CPUs.
'Мы просто хотим чемодан денег от Интел?' - а вот это уже достойная цель!
судя по тикету, они не хотят зависеть от LLVM-ных библиотек.
но это не мешает им использовать бинарники LLVM
Цель скорее имиджевая. Раст декларируется как замена дырявым Си/Си++, а под копотом втихаря у себя юзает "ллвмное сишное поделие". Более того, Раст не гнушается пользоваться сишной либси в недрах своей стдлибы. Не к лицу, какие-то "двойные стандарты". Попахивает ханжеством и лицемерием.
Извини, но твое сообщение выглядит как набор пафосных штампов.Никто втихаря ничего не юзает - о том что раст собирается ллвм'ом могут не знать только домохозяйки (и то не все)) - любой человек которые решил его установить, прочтет документацию.
По поводу либСИ - уже были попытки переписать (steed), думаю к этому еще вернутся.В любом случае добавление раст-кода к си-коду уже делает код лучше (хотя бы будет меньше use-after-free).
Добавление раст-кода к си-коду делает только необходимым поддерживать два языка вместо одного. Никакой код лучше от Раста автоматически не становится.
Можно утверждать с полной уверенностью, что становится хуже. Потому что ломается линковка, появляется зависимость от шланга и его стека (в том числе, от плюсовых либ), во многих случаях появляются случайные труднодиагностируемые зависания (и особенно это касается менее популярных платформ). Так что, если видишь растофанатика, смело плюй ему в лицо, он глупый и хочет тебе навредить.
пойди это librsvg расскажи.
все вы такие умеые и умелые в комментах языком чесать. а вот когда касается дела - то пшик.
> Более того, Раст не гнушается пользоваться сишной либси в недрах своей стдлибы. Не к лицу, какие-то "двойные стандарты". Попахивает ханжеством и лицемерием.Но двойные они только у опеннетных Военов Супротив Раста, сидящих тут с вендочки или мака и не знающих про штатный интерфейс взаимодейстия с *nix-ядрами ...
System calls and library wrapper functions
System calls are generally not invoked directly, but rather via
wrapper functions in glibc (or perhaps some other library).
...
Architecture-specific requirements
Each architecture ABI has its own requirements on how system call
arguments are passed to the kernel. For system calls that have a
glibc wrapper (e.g., most system calls), glibc handles the
details of copying arguments to the right registers in a manner
suitable for the architecture.
вон, на редоксе прекрасно обходятся без сишной либц (и даже предоставляют либц на расте для запуска сишко-софта).
Впрочем, Военам это ведь не помеха - как только появится "своя" версия, на расте, Воены хором начнут декларировать вторую часть своего Эпоса: "Опять NIH! Опять лишь переписали! Опять тянут в систему что-то свое, вместо использования уже готового системного!"
Совсем евангилисты раста обленились?Где тут сказано, что штатный интерфейс?
Где тут сказано что никто не может сделать библиотеку для работы с системными вызовами?
Бери, делай, работай. Поддерживать придется самому - это да.
И код поддержки разных архитектур и ядер придется писать самому - это то же да.
И да, как раз с этим у раста большие проблемы. Из-за заточенности на безопасности условная компиляция сложна в реализации. Из-за своеобразного взгляда на ООП такие реализации требуют мультиплексирования одних и тех же участков кода.
> Где тут сказано что никто не может сделать библиотеку для работы с
> системными вызовами?Совсем Воены овоенились - сами опять что-то придумали, сами оспорили.
> Бери, делай, работай. Поддерживать придется самому - это да.
> И код поддержки разных архитектур и ядер придется писать самому - это то же да.И слушать скандирования местных Военов "опять NIH! Опять тянут в систему что-то свое, вместо использования уже готового системного!" - тоже да.
> И да, как раз с этим у раста большие проблемы. Из-за заточенности на безопасности условная компиляция сложна в реализации.
// This function is only included when compiling for a unixish OS with a 32-bit
// architecture
#[cfg(all(unix, target_pointer_width = "32"))]
fn on_32bit_unix() {
// ...
}
Опять у Военов фантазия разыгралась ...
А теперь дай пример кода, где функции на разных архитектурах в качестве параметров принимают разные структуры. И как реализуется работа с двумя разными структурами двух разных архитектур одним кодом...Очень будем посмотреть!
> А теперь дай пример кода, где функции на разных архитектурах в качестве
> параметров принимают разные структуры. И как реализуется работа с двумя разными
> структурами двух разных архитектур одним кодом...
> Очень будем посмотреть!https://github.com/jasonwhite/syscalls/tree/main/src
Чутку глянул!Это вот прям сахарок:
https://github.com/jasonwhite/syscalls/blob/main/src/args.rs
>> А теперь дай пример кода, где функции на разных архитектурах в качестве
>> параметров принимают разные структуры. И как реализуется работа с двумя разными
>> структурами двух разных архитектур одним кодом...
>> Очень будем посмотреть!
> https://github.com/jasonwhite/syscalls/tree/main/srcТак где там разные структуры?
Вызов системного вызова по номеру и передача параметров им. Без интерпретации содержимого.Где сами системные вызовы разные на разных платформах?
> Так где там разные структуры?Папа, где море? (c)
> Вызов системного вызова по номеру и передача параметров им. Без интерпретации содержимого.
Сам что-то придумал, сам потребовал опровергнуть ... истинный Воен!
> Где сами системные вызовы разные на разных платформах?
pub unsafe fn syscall2(n: Sysno, arg1: usize, arg2: usize) -> usize {
let mut ret: usize;
asm!(
"syscall",
inlateout("rax") n as usize => ret,
in("rdi") arg1,
in("rsi") arg2,
out("rcx") _, // rcx is used to store old rip
out("r11") _, // r11 is used to store old rflags
options(nostack, preserves_flags)
);
ret
}
...
pub unsafe fn syscall2(n: Sysno, arg1: usize, arg2: usize) -> usize {
let mut ret: usize;
asm!(
"svc 0",
in("r7") n as usize,
inlateout("r0") arg1 => ret,
in("r1") arg2,
options(nostack, preserves_flags)
);
ret
}
...
pub unsafe fn syscall2(n: Sysno, arg1: usize, arg2: usize) -> usize {
let mut ret: usize;
asm!(
"ecall",
in("a7") n as usize,
inlateout("a0") arg1 => ret,
in("a1") arg2,
options(nostack, preserves_flags)
);
ret
}
...
pub unsafe fn syscall2(n: Sysno, arg1: usize, arg2: usize) -> usize {
let mut err: usize;
let mut ret: usize;
asm!(
"syscall",
inlateout("$2") n as usize => ret,
lateout("$7") err,
in("$4") arg1,
in("$5") arg2,
// All temporary registers are always clobbered
lateout("$8") _,
lateout("$9") _,
lateout("$10") _,
lateout("$11") _,
lateout("$12") _,
lateout("$13") _,
lateout("$14") _,
lateout("$15") _,
lateout("$24") _,
lateout("$25") _,
options(nostack, preserves_flags)
);
if err == 0 {
ret
} else {
ret.wrapping_neg()
}
}
Забавно. Так где разные структуры то? Где один код обрабатывающий разные структуры?То что ты приводишь, это лишь малая необходимая часть для легкого переноса кода на разные платформы. Очень малая и сильно недостаточная.
> Забавно. Так где разные структуры то? Где один код обрабатывающий разные структуры?Забавно, пошли очередные "это не считаица, это тоже, а покажи мне диво-дивное, чудо-чудное ..."
В реализацию stdlib смотреть не пробовали?
https://doc.rust-lang.org/src/std/fs.rs.html#362-364
pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<File> {
self._open(path.as_ref())
}fn _open(&self, path: &Path) -> io::Result<File> {
fs_imp::File::open(path, &self.0).map(|inner| File { inner })
}
Правда, совсем не обязательно делать удаление гланд автогеном через одно место:
pub fn open<P: AsRef<Path>>(path: P) -> io::Result<File> {
OpenOptions::new().read(true).open(path.as_ref())
}
Там ведь под капотом не только лишь "вызовы нашей либц!"
impl File {
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
let path = maybe_verbatim(path)?;
let handle = unsafe {
c::CreateFileW(
path.as_ptr(),
opts.get_access_mode()?,
opts.share_mode,
opts.security_attributes,
opts.get_creation_mode()?,
opts.get_flags_and_attributes(),
ptr::null_mut(),
)
};...
impl File {
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
run_path_with_cstr(path, |path| File::open_c(path, opts))
}pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
let flags = libc::O_CLOEXEC...
#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "linux",
target_os = "emscripten",
target_os = "android",
target_os = "solaris",
target_os = "illumos",
target_os = "haiku",
target_os = "l4re",
target_os = "fuchsia",
target_os = "redox",
target_os = "vxworks",
target_os = "espidf",
target_os = "horizon",
target_os = "vita",
target_os = "nto",
))]
pub fn ino(&self) -> u64 {
self.entry.d_ino as u64
}#[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
pub fn ino(&self) -> u64 {
self.entry.d_fileno as u64
}
> Забавно, пошли очередные "это не считаицаИзначально речь и шла про невозможность одним кодом разные структуры обрабатывать. Что ты из раза в раз и подтверждаешь примерами, где сплошное дублирование.
Где хот отдаленно похожее на это:
https://codebrowser.dev/glibc/glibc/libio/iofopen.c.html
Не говоря уже об этом:
https://codebrowser.dev/glibc/glibc/nss/getXXbyYY.c.html
Вот просто такое:
#ifdef _IO_MTSAFE_IO
new_f->fp.file._lock = &new_f->lock;
#endif?
>> Забавно, пошли очередные "это не считаица
> Изначально речь и шла про невозможность одним кодом разные структуры обрабатывать. Что
> ты из раза в раз и подтверждаешь примерами,Изначально речь шла о "И да, как раз с этим у раста большие проблемы. Из-за заточенности на безопасности условная компиляция сложна в реализации. ", остальное - уже фантазии Военов.
> где сплошное дублирование.Вызов WinAPI на венде - дублирование open на nix, так и запишемю
> Где хот отдаленно похожее на это:
> https://codebrowser.dev/glibc/glibc/libio/iofopen.c.html
> Не говоря уже об этом:
> https://codebrowser.dev/glibc/glibc/nss/getXXbyYY.c.htmlКакой "отличный" пример "кросплатформы" - линух-онли либа.
> Вот просто такое:
>
> #ifdef _IO_MTSAFE_IO
> new_f->fp.file._lock = &new_f->lock;
> #endif
>
#[cfg(any(
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly"
))]
pub fn ino(&self) -> u64 {
self.entry.d_fileno as u64
}
"Папа, где море?"(с)
Опять. Вот опять приводишь пример в котором полный вызов функции.И? Опять показал проблемы раста.
В очередной раз показывая на .вно говоришь, что это съедобно.
Вот реально сказочный Ваня или просто изображаешь?
> Не очень понятно 'зачем'?зачем независимость ? внезапно чтобы не зависеть от прихотей левой пятки трансгендера
А он не может написать хороший код?
Может ты не сможешь им пользоваться? Как это у вас называется, "зашкварно"?
Или скрепы разогнуться?
> А он не может написать хороший код ?пусть хоть волшебный код будет - кто думает о будущем не подсядет на вендорлок, поматросил и бросил в таких случаях лучшая стратегия
Так эти трансгендеры код не пишут, они максимум на маркдауне в CoC контрибутят.
Чтобы весь тулчейн Zig был написан на компактном и быстром Zig и не тянул за собой тонны легаси.
а может Zig такой компактный и быстрый как раз за счет использования LLVM?
такие простые мысли тебя не посещали?
:) надо быстрее в своп ложиться...
>Кроме того, потребление памяти в многопоточном режиме может значительно возрастать, например, в тестах наблюдался рост потребления памяти до 35%.Возрастать по сравнению с многопроцессностью? Не верю.
Вполне может. Если там насовали лок на каждый указатель и используются обильные мелкие структуры - 35% - это ещё не предел.
Многопроцессность не отменяется, как и раньше каждый крейт компилируется в отдельном процессе, однако теперь каждый из этих процессов может использовать несколько потоков при компиляции (При кодогенерации оно и так использовало многопоточность llvm)
Надеюсь, додумаются всё в 1 процесс засунуть и параллелить только одними потоками.
> Надеюсь, додумаются всё в 1 процесс засунуть и параллелить только одними потоками.А какой смысл?
Ну что ты как маленький? Чтобы потребители Коры Дуба™ были счастливы.
Собаки лают, караван идёт...
Собаки распараллеливают - караван идет8 потоков и на 50% быстрее. Каждый поток добавляет 6%... Питон, вроде, "параллельнее" будет.
Они ещё не познали всю силу фрагментирующего дефрагментатора.
У меня и козырь припасён. А как насчёт дефрагментирующего фрагментатора?Всё братья, простите грешника, спаааать!
Собаки лают, а все как писали на Си и С++, так и пишут.
Лучше бы сборку из GCC завезли. Go можно собрать из GCC, а сабж - нет.
Не переживайте. Люди этим занимаются.
go-gcc не собирает многие приложения. А м6огие собранные - крашатся.
Учитывая, что на расте ничего не написано, то хватит и сборки немногого. Главное, что не придётся тащить этот мерзкий тулчейн (а шланг и вовсе компилируется вечность).
>расте ничего не написано
>не придётся тащить этот мерзкий тулчейнтак если ничего не написано, то зачем таскаешь?
мазохист?
Firefox, pyca/cryptography, librsvg. Ни одной другой причины нет.
сборка больших проектов и так задействует все ядра, так как производится в несколько процессов. А для небольших проектов время компиляции - явно не бутылочное горлышко.Если кто еще не понял, для чего это все делается, то - чтобы ускорить искусственные хелловорлды, впечатлить CEO, добавить круто выглядящие строчки в резюме и освоить деньги спонсоров. Собственно, весь раст как язык был изначально создан с такими целями.
Эффективным менеджерам не нужен быстрый и эффективный язык, им нужно нечто с помощью чего можно бесконечно доить проект переписываниями и фиксами. Вот они и проталкивают Раст, специально спроектированный для этого.
а в дневных билдах хрома и фаерфокса распараллелено уже все что можно.
только жрать меньше они не стали.
еще раз для непонятливых: ловкая утилизация системных ресурсов не является оптимизацией производительности.
Но, погодите-ка, ведь раст изначально разрабатывался с поддержкой многопоточности "из коробки", как так получается, что многопоточная компиляция появляется только сейчас, спустя 15 лет с начала его разработки?
Ты не путай многопоточное исполнение и компиляцию
Компилятор может вообще быть на совершенно другом языке (и потом быть переписан на свой же язык, но не всегда)
Раст начинал с окалма, ГнуСИ с волосатого паскаля.
А он и не путает. Он спрашивает, как так получилось, что сами сапожники остались без сапог.
А они собирались делать себе сапоги? Или сам придумал)?
Насколько я помню историю то выбор ллвм был почти сразу.
Это отличный способ получить кучу профита из коробки и не придумывать велосипеды без сильной необходимости.
Интересен другой вопрос: а как так получилось, что лучшие разработчики на планете собрались на этом ресурсе и разучились читать?
> Но, погодите-ка, ведь раст изначально разрабатывался с поддержкой многопоточности "из
> коробки", как так получается, что многопоточная компиляция появляется только сейчас,А зачем "домохозяки", очевидно считающие что можно было просто сделать "запусти_много_потоков(синтактический_анализ_сорса)" интересуются?
Параллельная компиляция в rustc есть уже давно (этап генерации кода), просто сейчас дело дошло до распараллеливания фронтенда. Очевидно, проблемы решаются по мере возникновения и по важности. А как с параллельной компиляцией обстоят дела у других компиляторов, позвольте узнать?
А где конкретные цифры по проектам? Ну к примеру насколько сам компилятор стал быстрее собираться? Что это маркетинговые байки
Если перейти по ссылке в статье в блог - то там можно найти ссыль на гитхаб
https://github.com/rust-lang/compiler-team/issues/681
там есть примеры изменения времени компиляции разных либ (напр Serde, hyper, regex и тд)Спойлер: ускорилось от 11 до 47%, в среднем 30%
Under 8 cores and 8 threads, the parallel front end can reduce the clean build (cargo build with -Z threads=8 option) time by about 30% on average.
"для очень маленьких программ, которые и так компилируются быстро, компиляция в многопоточном режиме может выполняться медленнее" - то есть общая скорость компиляции хелоуворлдов растишек в итоге только уменьшилась.
Не переживай за них так. На самом деле скорость компиляции не изменилась, потому что определяется скоростью скачивания миллиона крейтов от которых зависит их хеловрот.
На целых 2%. Возможно, ты слышал о таком понятии, как "компромисс". Это такая штука, которую приходится реализовывать примерно в 95% решаемых задач в реальном мире.