Pull to refresh

Comments 78

До "собирается на современных платформах" всё же ещё далеко, пока что этот форк работает только под линукс

ioquake3 должен работать на всех платформах, согласно README вот тут: https://github.com/ioquake/ioq3. Совершенно точно он работает под macOS.

Исходный ioquake — вполне собирается и под windows. Но сравнивая репозитории очевидно, что winows-specific вещи исключены

В исходном коде платформо-специфичные вещи исключили, потому что форк базируется на SDL2. Этот порт точно работал под Windows ещё пару лет назад — сам качал тестовые билды с сайта форка, чтобы никого не обделить на lan party в офисе ). Сейчас раздел пустой из-за взлома сборочной инфраструктуры, поэтому придётся собирать самому.

Время сборки исходников компилятором сильно отличается?

rust делает билд за 30 сек, судя по видео. А транспиляцию за 1:40 сек примерно.
Осталось понять сколько делает все компилятор на С на такой же машине. Мне тоже интересно сравнить.
Объясните мне пожалуйста, а зачем это всё?
Исследовательский проект, можно понять много всякого, пока он делается. Так же спрашивали «на кой черт пыжиться kernel CLang-ом собирать, есть же GCC». Узнать что-то новое о наших инструментах)

Ну и возможно кому-то на практике пригодится тулза которая конвертит исходники на C, например, какой-нибудь видео encoder, скажем, AV1 ;)

Что Сишный, что ржавый вариант на 60% состоят из ассемблерных вставок под платформенные SSE. Это скорее что-то из разряда "как не переписать все на Rust". Есть какая-то легаси либа в проде, которая вроде и работает, но код ужасно пахнет, тестов толком не было и допилить что-то к ней надо. Скармливаем в C2Rust, допиливаем напильником и запиливаем недостающие фичи и используем как drop-in решение.

Такое как раз лучше и не трогать или уж переписывать как надо. Смысла в конвертации около нуля и +N новых багов.

Я имел ввиду ситуацию, когда к этому нужно новый функционал. Или есть какие-то странные плавующие SEGFAULT. Или есть завязки на другие либы, которые уже работают, но не имеют порта (типа SDL какой-нибудь для геймдева).
А вообще было бы неплохо если б кто-нибудь взялся перевести пару постов по теме (раз, два). В первой статье конвертация помогла избавиться от древненего незадокументированного косяка, как пример. Где-то тут же на хабре была статья про сферический анализатор текстов в типографии, который надо допиливать и в Си-лэнде оно оставляет много проблем как с IO так и с доступом к памяти, но это уже про полноценный RIIR, не про конвертацию.

А что, конвертация в Rust настолько умная, что поможет с плавающими SEGFAULT в С?

UFO just landed and posted this here

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


Оригинальная заметка со второй статьи
As an aside, this test was originally written to nest things three layers deep (e.g. top_level.vm includes nested.vm which includes really_nested.vm) to make sure it handles more than one level of %include, but no matter how it was written the test kept segfaulting.
Then I tried running the original C tvmi binary…
$ cd vendor/tinyvm/
$ cat top_level.vm
%include nested
$ cat nested.vm
%include really_nested
$ cat really_nested.vm
Hello World
$ ./bin/tvmi top_level.vm
[1]    10607 segmentation fault (core dumped)  ./bin/tvmi top_level.vm


Turns out the original tinyvm will crash for some reason when you have multiple layers of includes

какой-то детский сад получается

Что? Это та сотня строк асма, которая компилируется лишь в случае целевой платформы x86?

https://github.com/xiph/rav1e
Assembly 57.2%
Rust 42.5%
Other 0.3%
sloc на репу не травил, поэтому сколько сотен строк asm там не знаю. в сишной имплиментация похожая история.

А руками исходник-то не смотрели (ох, люблю я русский язык)?
Или, может, там под assebmly другое подразумевается?
Вообще-то Кармак не любил ассемблер начиная с первого Doom, даже там его самую чуточку.

Ну, так кармак игры писал, а не выжимал из железа каждый бит. Производительность кода — скорее побочный эффект, необходимый для комфортной игры, нежели цель. У кодеков же бенчмаркинг едва ли не такты считает ради оптимальнейшей утилизации ресурсов железа, чтоб обработка чуть ли не в скорость шины данных упиралась, энергоэффективность тут же рядом.
Да, исходники смотрел, но по большей части уделял ржавой части и arm neon. Не слишком детально, конечно.
У сишного dav1d cхожие автометрики. Нюанс в том, что ассемблерный код не слишком компактный и десяток строк высокоуровневого языка вполне может вылиться в пару сотен строк на asm, а метрики gitlab и github почти наверняка ориентируются именно на sloc ничего удивительного, что "10 строк" asm не очень десять, а половина значимых возвратов каретки в репе

Интересно, пришло ли подтверждение того, что Rust действительно легче в написании и поддержке, безопаснее и т.д.?
Код покрыт ансейфами абсолютно весь:
$ find ~/prog/ioq3 -name "*.rs" | xargs cat | grep unsafe | wc -l
9241


Ну это так, чтобы оценить масштаб проблемы
$ find ~/prog/ioq3 -name "*.rs" | xargs cat | grep fn | wc -l
9740

Это игрушки из серии C++ в Java получаются — никакого коммерческого смысла подробные конвертации не имеют.
Что, в принципе, и ожидалось.

<offtop>


Код покрыт ансейфами абсолютно весь

Пропел на мотив "Острова невезения". Захотелось записать переделку. Хабр, ты что творишь...

UFO just landed and posted this here
Пока есть много спецов, которые умеют справлятся с C и C++ и нужны как для новых, так и для существующих проектов, пока индустрия не начнёт осознавать что проблемы с этими языками куда дороже чем поиск/обучение специалистов на раст, то ожидать перехода не стоит. Тем более что индустрия C/C++ куда более консервативна и фундаментальна, чем прикладное ПО или веб, где сейчас ты пишешь на React JS, а завтра уже пишешь на Dart или ClojureScript, так как это хайпово, а бизнес требует выпускать всё больше новых и модных продуктов в короткие сроки. В системной же нише решения создаются на годы вперёд и держат над собой все эти прикладные вещи, и переход на новый язык требует оценки рисков, а сама технология и языки — долгой, многолетней «обкатки», после которой он получит признание. И то, в лучшем случае только для новых проектов, так как переписывать старые редко имеет смысл.
А ещё MS задумал свой раст с преферансом ну и так далее. Вот они смогут толкнуть его(свой вариант).

+1 стандарт? Не, спасибо, нам такого не надо — раста достаточно.

UFO just landed and posted this here
как раз было бы счастье, если бы MS сделал нормальный тулинг и нормальный синтаксис, да и своим примером показал как они с сишечки переезжают

Да что вам в этом синтаксисе не нравится-то всё...

Синтаксис Раста кажется страшным только до тех пор, пока вы не начнете писать на нем программы )

С их слов это не форк языка (надеюсь), но сам факт того, что индустрия начала интересоваться — хороший знак. Прошлой осенью ещё предлагали писать драйвера для линукс ядра. Хоть это и будет опциональная вещь, но она явно создаст первый крупный прецедент.
Проект верона… они ругали раст за медленную скорость разработки, вот-вот только асинки появились, а в шарпе они были когда. Просто Rust — это коллективный продукт, решения принимаются медленно но верно, а корпорация, конечно, может быстрее в десять раз сделать, лишь бы не испортила.
я надеюсь только на с лайк синтаксис, мне растовый не нравится.
Сейчас немодно писать тип впереди переменной, все новые языки пишут через двоеточие после, а для функции через стрелку, как же можно идти против тренда :)
«Да вы что, не знаете, что в однобортном сейчас уже никто не воюет?» ©

Это связано не с трендом, а с выводом типов в различных контекстах (объявление локальной переменной — это лишь один из них).
Когда создавали C, о выводе типов не задумывались, а когда задумались, то позже, в C++, вынуждены были лепить костыли.

Длинный женерик указывать перед именем, да еще через пробел — это понятно, очень нечитабельно, особенно если перед именем функции, кому такое может понравиться, а про вывод типа не понял.
Видимо, имеются в виду случаи типа такого, когда return type функции выводится из типов ее аргументов. Для подобных случаев в C++ тоже сейчас добавили стрелочный синтаксис.
в С++14 такое есть не только для лямбд с их стрелочным синтаксисом, но и для обычных функций:
template <typename T1, typename T2>
auto add(T1 lhs, T2 rhs) { return lhs + rhs; }
Ну это хорошо, конечно, если тело функции идет тут же, а если это предварительное объявление?

template <typename T1, typename T2>
decltype(lhs + rhs) add(T1 lhs, T2 rhs);

не прокатит, lhs/rhs was not declared in this scope. А вот такое:

template <typename T1, typename T2>
auto add(T1 lhs, T2 rhs) -> decltype(lhs + rhs);

прокатит без проблем.
вопрос в рамках самообразования, а почему такое нельзя?
template <typename T1, typename T2>
decltype(lhs + rhs) add(T1 lhs, T2 rhs);
Ну, очевидный ответ — потому, что на момент парсинга конструкции с decltype про lhs и rhs еще ничего не известно, так как они объявлены позже. Менее очевиден ответ на вопрос, почему на такой случай не сделали какое-нибудь «исключение из правил» для парсера, этого я точно не знаю, не берусь ничего утверждать.

если про lhs + rhs ничего не известно на момент парсинга decltype(lhs + rhs) — то это совершенно не проблема. Проблема возникает, если такие переменные объявлены выше по коду.


double lhs;
double rhs;

decltype(lhs + rhs) add(int lhs, int rhs);

Какой тип результата по твоему должен быть у функции ??

Ну да, такое тоже может быть.

мда уж, трапчик.

потому что неправильно написано. должно быть
auto add(int lhs, int rhs) -> decltype(lhs + rhs) ;

Потому что изначально template<> и существует для того, что-бы определить все параметры шаблона до сигнатуры. decltype() появился позже. Правда непонятно зачем тут decltype, ведь в С++ есть вывод типа возврата.

Смысл переписать есть, денег нет, зачастую.

Переписывание ради переписывание тоже смысла не имеет — только если есть какие-то значимые бенефиты.

Посмотрел ioquake3/src/server/sv_init.rs, вспомнил выражение:
Программист на Фортран может писать на Фортране на любом языке программирования.

Это вы еще не видели результаты работы интеловского транслятора из OpenCL в Verilog для их FPGA. Вот там веселые идентификаторы в десяток строк существуют.
Хотя и задача посложнее, чем перевод одного последовательного языка в параллельный.

Мало им «окисления» Firefox, rsvg, теперь за ioQuake взялись, вместо того чтобы Crates.IO сделать offline-совместимым как PyPi, cpan.

Нужно по возможности защитить весь Open-Source софт от этой заразы путем форка.
Это что, есть порты Doom и Quake на дельфи. И все живы-здоровы, никто не умер.
В случае с Delphi это были эксперименты по портированию. Игры с портированием на Rust заканчиваются тем что на него переключают основную ветку разработки, посмотрите на теже Firefox и rsvg, новые версии без Rust просто не собираются.
Какая основная ветка нафиг? IOQUake3 сам по себе форк.

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

Отличная новость! Если есть решение, значит проблема таки была.

Нажать на кнопку «Нравится» не могу, заминусовали.

Кто наставил минусов, убирайте, я был прав, указанная мной проблема с использованием Rust в оффлайне имела место!

А где же фраза "го вместе защищать, я создал"?

Вместе не получится. Многим не до этого, много народа на винде сидит им плевать на опенсорс.

Лично я играю в Urban Terror, который на ioquake3 крутится. Каждую неделю, каждый месяц, каждый год к ряду играю — это уже часть моей жизни.
А главное — где сравнение pps (popugaev per second)?
Результирующий код напомнил времена, когда HTML страницы делали в MS Word
Если копнуть C2Rust чуть глубже, то можно обнаружить, что там есть инструменты для полуавтоматического переноса результирующего кода на идиоматичный раст. Но авторы решили не заморачиваться, а жаль.

А зачем может быть нужен указатель за пределами массива?

указатель в принципе может указывать на ЛЮБОЙ адрес в памяти. NULL — так-то это тоже адрес ЗА пределами массива. Так что если так рассуждать, то от указателей надо переходить к индексам и итераторам, но, внезапно, мы сразу теряем в эффективности работы


Только в сорсах ioq3 индекс с выходом за пределы массива используется для проверки указателя на выход за пределы массива. Rust проверяет это в рантайме. Проще при рефакторинге перейти как минимум на индексы, а не указатели, это раз, а второе — работа с такими абстракциями, как итераторы, в Rust — это zero-cost.

аргумент принимается )

nullptr — это таки другое.
Ну и NULL :


  • не обязан быть 0
  • 0 не обязательно невалидный указатель

Абсолютно верное замечание, но тогда надо четко отделять — мы про С или с++ говорим и какого стандарта )

if (p >= &array[1024]) {
   // error...
}

это они так выход за границы массива проверяют.

Потому что иногда (на самом деле часто) имеет смысл рассматривать указатели как указывающие не на элемент массива, а на границу между элементами. А таких границ всегда можно провести на одну больше, чем в массиве элементов...

Только в исходниках это используется не в каких-то массивах, находящихся в структурах, а в тех, что лежат в локальном стеке функции. Работать в этом случае с такими массивами через указатели — не очень ок.
А бенчмарки есть растовой и исходной версии?
На реддите обсуждалось. Авторы не делали никаких замеров. Ограничились тем что версия на расте выдаёт стабильные 90 fps. Там где-то в настройках стоит лок на максимальный fps
Sign up to leave a comment.

Articles