LINUX.ORG.RU

Презентация «Rust - лучше, чем C++» на русском языке от разработчика из Яндекса

 


7

3

http://tech.yandex.ru/events/cpp-party/june-minsk/talks/1978

Степан Кольцов

Яндекс

Rust — это современный, практический, быстрый и безопасный язык программирования. Некоторые говорят, что Rust — это как C++, если бы его писал человек, знающий Haskell.

Система типов Rust решает главную проблему C++ — небезопасность. C++ очень легко сделать ошибки, которые приведут к поломкам (например, use after free). Rust позволяет писать безопасный код, сохраняя при этом выразительность и околонулевые накладные расходы C++. В докладе будут подробно описаны механизмы языка, которые контролируют безопасность программы.

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


Ответ на: комментарий от backbone

для разработки требовательных к ресурсам программ будет необходим именно Rust

А для нетребовательных - Си?

А Си будет тупо не нужен переименован в легаСи.

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

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

Стоящий crap выйдет примерно где-то после 23-27 версии.

Да пофиг - строка это какая-то абстракция... ;)

Главное емакс настроить...

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

Он будет быстр, но не будет обладать возможностями Erlang VM по массовому запуску процессов.

Почему? Совсем так безнадежно?

Звучит то ли как реклама, то ли как история болезни.

Да гадость, да. Не стоит напрягаться и менять стереотипы.

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

Он будет быстр, но не будет обладать возможностями Erlang VM по массовому запуску процессов.

Почему?

Потому что это мало кому нужно в таком языке. Потому что нет VM.

Совсем так безнадежно?

Нет. Сделать можно, но тем, кто может, это не нужно.

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

Не имеет. В яндексе сейчас толковые разрабы есть разве что на картах, да и то...

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

Чего там тяжёлого? Boost.fiber посмотри хотя бы

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

1 OS thread, а в нем ровно 1 green thread.

А теперь можно выкинуть 1 green thread и продолжить пользоваться голым 1 OS thread, сэкономив немножко времени и памяти, которые мы тратим на ненужное управление этим одним зеленым потоком.

В модели с OS-only threads караулить число активных OS threads надо делать вручную.

Не совсем понял, что ты имеешь ввиду, но могу симметрично ответить, что в модели с green threads караулить число активных green threds надо вручную: рантайм не сможет за тебя решить, сколько процессов создавать.

Апгрейдятся до IO thread только те green threads, что неизбежно блокируются/виснут на долгое время

Об чем и речь, что при наличии IO, зеленые потоки превращаются в тыкву.

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

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

Ну так расскажи мне про нужность. А то у меня сложилось такое ощущение, что на сегодняшний день о пользе зеленых тредов говорят только всякие хипстеры и маргиналы, а в мейни-стриме их либо никогда не было, либо их оттуда уже давно выпилили (java). Только лучше не сам расскажи, а дай ссылку на статью умного человека.

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

Ты просто не понимаешь, что такое хвостовая рекурсия, или не можешь внятно выразить свои мысли. Ещё раз пишу — если в императивном языке приходится используется рекурсию, оптимизация хвостовых вызовов будет неприменима.

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

Ещё раз пишу — если в императивном языке приходится используется рекурсию, оптимизация хвостовых вызовов будет неприменима.

Что?

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

> 1 OS thread, а в нем ровно 1 green thread.

А теперь можно выкинуть 1 green thread и продолжить пользоваться голым 1 OS thread, сэкономив немножко времени и памяти, которые мы тратим на ненужное управление этим одним зеленым потоком.

Твой рукописный менеджер будет подозрительно похож на green thread runtime manager. Будет тот же набор данных, что и в Презентация «Rust - лучше, чем C++» на русском языке от разработчика из Яндекса (комментарий). Только вместо стека какое-то другое представление данных задачи.

> В модели с OS-only threads караулить число активных OS threads надо делать вручную.

Не совсем понял, что ты имеешь ввиду, но могу симметрично ответить, что в модели с green threads караулить число активных green threds надо вручную: рантайм не сможет за тебя решить, сколько процессов создавать.

green threads не надо караулить - они и так по одному активному на один OS thread. Остальные ждут своей очереди. Число OS threads выбрать легко: сколько CPU - столько и OS threads (+ OS threads для тех случаев, когда без них никак). Но можно и вручную задать.

> Апгрейдятся до IO thread только те green threads, что неизбежно блокируются/виснут на долгое время
Об чем и речь, что при наличии IO, зеленые потоки превращаются в тыкву.

(сорри, там опечатка: s/IO/OS/) При условии, если рантайму совсем лень управлять I/O.

Но обычно примитив 'READ fd' в языке реализуется как 'RUNTIME_WAIT_READ fd; READ fd'.

Если в программе один зеленый поток на всю систему - 'RUNTIME_WAIT_READ' ничего не делает, а если больше одного - runtime юзает select/poll/epoll/whatever(обычно чуть сложнее) на всех зарегистрированных через 'RUNTIME_WAIT_READ' дескрипторах для вычисления green threads, у которых появилась возможность произвести I/O.

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

green threads не надо караулить - они и так по одному активному на один OS thread.

1)тогда это подозрительно похоже на очередь задач, а как же переключение?

2) всегда должен быть поток, который отслеживает выполненные задачи и скармливает потокам новые.

RedPossum ★★★★★
()

решает главную проблему C++ — небезопасность

Кто сказал им, что это главная проблема ?

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

> green threads не надо караулить - они и так по одному активному на один OS thread.
1)тогда это подозрительно похоже на очередь задач, а как же переключение?

Об этом и базар :]

Обычно переключение - кооперативное. Компилятор гарантирует, что поток не будет работать «слишком долго» и вставляет точки переключения. Из-за того, что они хорошо определены (например, «прямо перед I/O», или «прямо перед GC») переключение контекста совсем легко реализуется.

Для снятия с исполнения вручную обычно тоже доступен примитив 'SCHED_YIELD'.

Можно и вытеснять (по SIGALARM, например), но тогда надо генерить код, который к этому готов в любой момент.

2) всегда должен быть поток, который отслеживает выполненные задачи и скармливает потокам новые.

Зеленые Потоки сами выполняют реальный код - себе данные и добывают (создают новые потоки, читают данные из ядра, etc.). Взаимодействют с рантаймом для повышения эффективности планирования.

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

Твой рукописный менеджер

Какой рукописный менеджер, ты о чем вообще? Понадобился поток - создал поток (нативный) и забыл. Дальше пусть ОС занимается переключением. В этом же вся идея: ОС все равно потоками рулит, так зачем пихать в рантайм еще один менеджер потоков (зеленых) и тратить на него ресурсы?
Нужно твоему этому потоку заблокироваться - пусть блокируется. На другие потоки это не влияет, и городить костыли в рантайме, чтобы блокирование зеленого потока не блокировало менеджер зеленых потоков, тоже не нужно.

ПС: У меня складывается ощущение, что ты либо сам не очень понимаешь, о чем говоришь, либо забыл упомянуть о чем-то важном, без чего твои речи теряют смысл.

ddos3
()

Лишь бы сишечку не трогали. А со своими недоЯПами пусть что угодно делают!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от sf

Зеленые Потоки сами выполняют реальный код - себе данные и добывают (создают новые потоки, читают данные из ядра, etc.)

а как OS Threads себе потоки добывают?

RedPossum ★★★★★
()

Было бы прикольнее, если бы они сумели сделать что-то, что хуже C++.

Некоторые говорят, что Rust — это как C++, если бы его писал человек, знающий Haskell.

Я говорю, что Rust - это как Haskell, если бы его писал человек, знающий C++ (и ничего кроме).

Хотя в данный момент Rust ещё не подходит для использования в продакшне

И не подойдёт.

Во-первых, потому что это очень интересный подход к программированию

В нём нет ВООБЩЕ ничего нового.

или другой

Вот когда появится - будем изучать.

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

Я говорю, что Rust - это как Haskell, если бы его писал человек, знающий C++ (и ничего кроме).

Ты говоришь неправильно. Первый автор - окамльщик с довольно широким кругозором, у нынешней команды тоже довольно широкий кругозор (Haskell, ML, JS, CL, Си++).

В нём нет ВООБЩЕ ничего нового.

Ничего нового в смысле исследований. Это один из принципов его разработки.

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

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

ckotinko ☆☆☆
()
Ответ на: комментарий от ddos3

> Твой рукописный менеджер
Какой рукописный менеджер, ты о чем вообще? Понадобился поток - создал поток (нативный) и забыл.

Чем меньше задача ввода/вывода по вычислительным ресурсам - тем больше оверхед на создание потока.

Вы во сколько ~инструкций (ну совсем примерно) оцениваете время создания OS thread?

Вы во сколько ~инструкций (ну совсем примерно) оцениваете время переключения OS threads?

ПС: У меня складывается ощущение, что ты либо сам не очень понимаешь, о чем говоришь, либо забыл упомянуть о чем-то важном, без чего твои речи теряют смысл.

Думаю, что понимаю :] Видать чего-то не досказал.

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

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

Хороший пример. Реализовать вообще ничего не мешает, но на холяву есть не везде.

Обычно «ненужный язык» создается, чтобы решать не только (и не столько) эту задачу.

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

время создания OS thread

Зависит от ОС :) Знаю, что на линуксе выходит дорого, а на винде безумно дорого. С другой стороны, никто не заставляет на каждый чих создавать новый поток.

время переключения OS threads?

Это некорректная формулировка. Правильнее говорить о глобальном оверхеде планировщика ОС, который существует всегда и теоретически не зависит от количества потоков (планировщик, конечно, может быть реализован по-разному, и на винде, я слышал, очень сильно тормозит, если потоков становится много. Но кто поставил себе винду - тот ССЗБ). В пределах одной аппликации говорить о стоимости переключения нативных потоков не имеет смысла и следует принять ее за 0. Поэтому позволить ОС переключать потоки выходит дешевле, чем добавлять к оверхеду планировщика ОС еще и оверхед на управление несколькими зелеными потоками внутри одного потока ОС.

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

Первый автор - окамльщик с довольно широким кругозором, у нынешней команды тоже довольно широкий кругозор

Не вижу, как это противоречит тому, что я написал.

Ничего нового в смысле исследований. Это один из принципов его разработки.

А, понятно, это и есть «интересный подход».

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

> время создания OS thread

Зависит от ОС :) Знаю, что на линуксе выходит дорого, а на винде безумно дорого. С другой стороны, никто не заставляет на каждый чих создавать новый поток.

Ну в самом деле, не писать же свой менеджер потоков :]

OS - какая вам удобнее. Мне проще в linux (там должно быть не хуже всех). Лишь бы примерная цифра была. От нее будем плясать.

Правильнее говорить о глобальном оверхеде планировщика ОС

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

В пределах одной аппликации говорить о стоимости переключения нативных потоков не имеет смысла и следует принять ее за 0.

Как вы думаете, сколько байт занимают все userspace регистры в модных процессорах? (x86_64: GP, FPU, XMM, AVX) И все надо откуда-то из памяти прочитать/записать при переключении.

+ инвалидация кэша TLB: каждый поток имеет минимум одну приватнул область с TLS (та, что доступна по pthread_getspecific/setspecific, обычно адресуется сегментным регистром fs или gs)

Так во сколько инструкций оцениваете?

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

так это и будет нахаляву. libc + pthread пропатчить и все заработает. зачем язык то городить?

Это даст только более приличный IO.

В Rust, например, еще пытаются решить проблему висячих указателей и неинициализированных переменных.

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

если с симд и fpu не работать, то это состояние не трогают

ckotinko ☆☆☆
()
Ответ на: комментарий от Legioner

Ещё раз пишу — если в императивном языке приходится используется рекурсию, оптимизация хвостовых вызовов будет неприменима.

Чё?

int fact(n, a)
{
  if (n==1) {
    return a;
  } else {
    return fact(n-1, a*n);
  }
}
...
printf("%d\n", fact(5, 1));

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

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

как Haskell, если бы его писал человек, знающий C++ (и ничего кроме).

автор - окамльщик с довольно широким кругозором, у нынешней команды тоже довольно широкий кругозор

Не вижу, как это противоречит тому, что я написал.

Не видеть очевидных вещей - это мастерство.

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

Лишь бы примерная цифра была

Пусть будет примерно N.

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

...и при этом все равно раз в сколько-то миллисекунд происходит прерывание от таймера, переход в ring 0 с потерей кеша MMU, вызов планировщика, выбор нового потока (или того же самого, если другого активного нет), сохранение/восстановление контекста, выход из прерывания. В итоге не важно, сколько в системе бежит процессов/потоков, оверхед на всей этой процедуре будет приблизительно один и тот же. Да, я в курсе про плавающий таймер, но он не сильно влияет на происходящее.

Так во сколько инструкций оцениваете?

Пусть будет M.

От нее будем плясать.

Цифры есть, начинай плясать.

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

никто не заставляет на каждый чих создавать новый поток.

В этом вся фишка, чувак. В эрланге ресурсы, которые ты используешь в процессе, привязываются к этому самому процессу. Файлы и сокеты например автоматом закрываются, когда процесс умирает. И это очень удобно при создании большого количества изолированных друг от друга асинхронных компонентов. Если в процессе что-то не так и он вдруг упал, вм автоматом всё почистит, подобным образом как это делает юниксовое ядро для процессов (нативных процессов (те что fork), но не потоков).

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

Да он и в линуксе тормозить будет. Фишка опять же не в этом, а в том, что реализация шедулера в опять таки эрланговской вм очень проста (например нет приоритетов, обычный счётчик, считающий для процессов, не остановленных на io, время поровну). Из-за своей простоты этот шедулер будет работать быстрее ядрёного. Кроме того, при огромном количестве процессов переключение будет всё равно ~О(1), так как скорее всего у него внутри будет указатель на элемент связного списка структур процессов и что бы найти идентификатор следующего процесса нужно будет сделать охереть просто какую дорогую операцию, а именно разыменования указателя. Ну просто миллисекунды работы). Но конечно, всё это только про эрланг. Как там в русте сделано я не знаю, но не удивлюсь если по такому же принципу.

В пределах одной аппликации говорить о стоимости переключения нативных потоков не имеет смысла и следует принять ее за 0.

Ну охренеть просто. Лихо ты оверхед шедулера нивелировал. man clone что-ли. Даже не знаю что тебе посоветовать.

Кстати, про потоки в винде. Я слышал (правда это было лет 10ть назад), что у них там наоборот для потоков очень сильно всё заоптимизировано. А для процессов - нет.

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

Лихо ты оверхед шедулера нивелировал.

Ты не понял, наверное. Стоимость планировщика ОС считается глобально в масштабах всей ОС, и считать его стоимость в масштабах одного процесса некорректно. Поэтому сравнение «планировщик ОС» vs «планировщик ОС + костыль для зеленых потоков в рантайме», нужно сократить до «никаких лишних костылей в рантайме == 0» vs «костыль для зеленых потоков в рантайме».

В этом вся фишка, чувак.

Чувак, ты говоришь о какой-то узкой специфике, под которую, возможно, специально и заточен erlang (я с ним не знаком, поэтому судить не берусь). Но проблема специфики в том, что практически под любую НЁХ можно придумать крайне специфическую задачу, в которой это НЁХ будет полезно, однако полезности НЁХ в целом это не доказывает (и не опровергает). В обычной же жизни, параллелить задачу больше, чем по потоку на ядро смысла не имеет, а если при этом профит нивелируется оверхедом на создание процессов, то лучше просто забить и сделать все на одном ядре.

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

Не видеть очевидных вещей - это мастерство.

Ну, растолкуй, ежели они такие очевидные.

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

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

Ты прав конечно, но если бы Ритчи с Томпсоном думали бы так же, то человечество до сих пор бы сидело за трёхзадачным досом. Подумай зачем вообще придумали юникс с многозадачностью.

а если при этом профит нивелируется оверхедом на создание процессов

Так в том же и прикол, что создание процессов дешевле семечек. От сюда и профит.

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

в линуксе процесс это тот же поток. struct task_struct один и тот же. а все остальное шарится независимо - память, файловые дескрипторы и т.д.

man 2 clone

ckotinko ☆☆☆
()
Ответ на: комментарий от vertexua

а go уже занят

Гугл запрещает использовать Го кому-то кроме себя?

Не в «занятости» дело, в общем.

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

...и при этом все равно раз в сколько-то миллисекунд происходит прерывание от таймера

...

оверхед на всей этой процедуре будет приблизительно один и тот же

И в процентах вы его оцениваете в ... сколько %?

Переключение контекстов потоков интересно мерять в случае, когда потоки хоть немного друг с другом взаимодествуют (задачи, например, себе передают).

Иначе это задачи независимые. С тем же успехом могли бы быть разными программами, только переключение контекста еще чуть дороже.

sf ★★★
()

Система типов Rust решает главную проблему C++ — небезопасность

мне казалось это давно уже не проблема, не?

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

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

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

Вроде бы он тоже проектировался в качестве замены крестам

да, но не в системном программировании, удел Go это network/backend/web итд.

umren ★★★★★
()
Последнее исправление: umren (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.