Комментарии 71
Самые интересные и красивые фракталы Мандельброта, напоминающие мандалы, получаются при очень громадным зуме, порядка 1.0e³⁰⁰ и более. Но вот проблема, стандартные типы данных (даже таких как long double) не способны обеспечить нужную точность расчётов, из за пресловутого "машинного эпсилона", ограничивая увеличение максимум на 1.0e²³. В этом случае применяют библиотеки, производящие математические операции с числами произвольной точности.
Может имеет смысл попробовать применить CUDA для расчётов фракталов с громадным зумом?
Пытался найти такие библиотеки, но все безрезультатно
Попробуйте для примера Nanobrot Fractal Renderer. Там в исходном коде есть библиотека (nmblib) для работы с числами произвольной точности, (конкретно смотрите mpreal.h).
По каким координатам такая красота?
X=0.27533764774673799358866712482462788156671406989542628591627436306743751013023030130967197535665363986058288420463735384997362663584446169657773339617717365950286959762265485804783047336923365261060963100721927003791989610861331863571141065592841226995797739723012374298589823921181693139824190379745910243872940870200527114596661654505 Y=0.006759649405327850670181700456194929502189750234614304846357269137106731032582471677573582008294494705826194131450773107049670717146785957633119244225710271178867840504202402362491296317894835321064971518673775630252745135294700216673815790733343134984120108524001799351076577642283751627469315124883962453013093853471898311683555782404
Zoom=9e300
Не понимаю при чем тут зум? Разве фрактал - это не самоподобная фигура? То, что на фото не похоже на исходный фрактал...
Посмотрите видео, как изменяется фрактал Мандельброта с увеличением зума до 3.9e¹⁴²⁹. И в итоге (конец видео) Вы увидите изначальный фрактал, вот Вам и самоподобие ) https://www.youtube.com/watch?v=thlvdXfl0KA
Вроде как, фрактал не обязательно самоподобен. Если я правильно понимаю, главное - это дробная размерность в математическом смысле.
Совершенно верно. Пример тому - фракталы Ляпунова, которые могут изображать интересные сюрреалистические картины 😉
Класс :-) Интересно, а сколько вообще известных разновидностей фракталов существует? Десятки, сотни?
Десятки это точно. Если Вы интересуетесь фракталами, могу порекомендовать интересный ресурс https://fractalforums.org/ где энтузиасты со всего мира общаются, делятся своим опытом, а также публикуют фракталы в персональных галереях.
Весь код доступен на Github - https://github.com/0x7o/mandelbrot_set Было удобнее работать с классическим RGB.
Что касается rust_gpu - это очень ранний проект, который пока не поддерживается стабильными версиями Rust
Ну так классический RGB выглядит точно также и в u8 превращается пачкой простых битовых сдвигов
fn int_to_vec3(color: u32) -> [u8;3] {
let r = (color >> 16) as u8;
let g = ((color & 0xff00) >> 8 ) as u8;
let b = (color & 0xff) as u8;
[r,g,b]
}
fn main() {
let [r,g,b] = int_to_vec3(0xFFAABB); // vs "#FFAABB"
println!("{:X} {:X} {:X}", r, g, b ); // prints "FF AA BB"
}
Такой ещё вопрос к автору: по какой причине Вы использовали именно Rust в смеси с С++, когда можно было данный проект сделать полностью на С++?
В целях практики с языком Rust. Его я активно изучаю в последнее время
А можно поинтересоваться, что такого имеется в Rust, чего нет в С++?
P.S. C Rust вообще не знаком.
Для меня главным фактором в пользу Rust стала безопасность работы с памятью
ИМХО, если в C++ пользоваться только контейнерами и не пользоваться сырыми указателями, тоже проблем с памятью не будет. Ну да, я знаю, что всякое возможно, но вероятность уж точно сильно снижается.
Как то привычка сложилась: выделил память - освободи. Хотя умные указатели скорее всего и ввели чтобы забыть об освобождении )
Не обязательно умный указатель, можно std::vector использовать.
std::vector это само собой, но это по сути динамический массив. А когда нужен указатель, например, на единственный объект класса? Использовать std::vector для него одного как то коряво получается. а std::unique_ptr<T> или std::shared_ptr<T> - как раз для такого случая.
А когда нужен указатель, например, на единственный объект класса?
Зачем тогда вообще указатель? Можно объект создать на стеке, или как член класса, и передавать ссылку на него, куда нужно. В том числе можно передать константную ссылку в те места, где не предполагается, что содержимое объекта может быть изменено. Дополнительная защита от ошибок.
Создавать на стеке имеет смысл, когда объектов относительно мало. Сталкивался с таким что Visual Studio выдаёт предупреждение о превышении размера стека, вариант с заданием размера стека типа #pragma comment(linker, "/STACK:размер_стека")
не есть хорошо, по сему если много объектов то нужно их создавать в куче.
Тут надо смотреть, почему объект занимает много места на стеке. Если внутри него много массивов, создаваемых на стеке, имеет смысл эти массивы сделать динамическими.
Статических массивов в нём нет, просто много классов, экземпляры которых создаются на стеке. Перевод их в кучу ничего не изменил в работе программы, однако потребовалось некоторое время для замены '.'
на '->'
. За это я и недолюбливаю С++, что если изменить способ создания объекта, придётся переделывать уйму кода, в Delphi, например, всегда '.'
. 😉
Если компилятор кидается предупреждениями про большой размер стека, но программа при этом работает, можно ничего не трогать.
в Delphi, например, всегда
'.'
Кто-то это может считать плюсом, а по мне, так я лучше буду сразу видеть, что по -> я обращаюсь к указателю. Который бывает нулевым, например, и поэтому нужно с ним обращаться с осторожностью.
Если компилятор кидается предупреждениями про большой размер стека, но программа при этом работает, можно ничего не трогать.
В том то и дело, программа на первый взгляд работает нормально, однако некоторые её функции начинают вести себя странно.
Кто-то это может считать плюсом, а по мне, так я лучше буду сразу видеть, что по -> я обращаюсь к указателю
А какая собственно разница каким оператором можно получить доступ к полям указателя класса '.'
или '->'
?
Можно например предварительно разименовать указатель, и получить доступ через '.'
, что то вроде:
*(a).b == a->b
Можно много чего, вопрос - зачем. a->b мне сразу говорит о том, что a - указатель. И если при отладке программа в этом месте вышла из строя, первая мысль - надо проверить, не нулевой ли указатель. Конструкции *(a).b для меня мне менее очевидны и загромождают код, зачем так писать?
Впрочем, на Паскале я не пишу, поэтому мне не с чем сравнить. К чему привык, тем и пользуюсь.
Ну так во многих языках программирования, доступ к полям структуры или класса осуществляется через '.'
, а указатели явно существуют в гораздо меньшем количестве языков. Молодёжь, пишущая на Python или JS, лишь за редким исключением, вообще про такую штуку как указатели вообще не знают 😉
Enum с нагрузкой (aka Tagged Union), минималистичные NewType и tuple, удобные опционалы (Result/Option), нормальные интерфейсы (trait), паттерн матчинг (aka сопоставление с образцом). Относительно простая и единообразная работа с итераторами, рэнжи и срезы из коробки, также как и структурное связывание, да ешё и с валидацией.
Ну и всякого по мелочи, типа чистых макросов, которые ещё и декоратором можно сделать, f-string-like форматирование, тесты, бенчмарки, доки и куча иного инструментария из коробки, время компиляции чуть меньше чем тепловая смерть вселенной и прочее.
Фичи которые тоже есть у раст, но многим не заходят: ручное управление временем жизни, границы типов (aka bounds), работа с асинхронными функциями и разделение на красные-синие.
Автор скорее всего толком не пользовался языком, чтобы что-то про "безопасности памяти" рассказать и как-то столкнуться с ней (учитывая что там сходу unsafe), так что считайте из-за хайпа зашёл.
рэнжи и срезы из коробки, также как и структурное связывание
ranges и структурное связывание есть в C++. В Rust что-то еще к этому добавили?
Автор скорее всего толком не пользовался языком, чтобы что-то про "безопасности памяти" рассказать и как-то столкнуться с ней (учитывая что там сходу unsafe), так что считайте из-за хайпа зашёл.
В данной задаче, ИМХО, кроме как "поизучать раст", нет никакой необходимости именно на нём писать, особенно в свете того, что часть всё равно на C++. Но в целом за статью автору респект однозначно.
время компиляции чуть меньше чем тепловая смерть вселенной
На любом языке можно написать такое, что будет компилироваться бесконечно долго. Я не имею ничего против Rust :-) просто без конкретного примера утверждение непонятно о чем.
ranges и структурное связывание есть в C++. В Rust что-то еще к этому добавили?
21/23 стандарт ещё не раскатали толком, плюс не все алгоритмы (пока?) красиво стыкуются в красивые пайплайны. Да и рэнжи нужно явно конструировать. В Rust они на уровне языка.
У плюсов отсутвует (пока?) возможность отбросить неиспользуемые биндинги, нельзя биндиться из массивов. Live
let vec = vec!(1,2,3,4,5,6,7);
// похоже на spread operator в js
// связываем содержимое вектора с переменными
let [a,b,c,..] = vec[..] else { unreachable!()};
println!("{a} {b} {c}"); // 1 2 3
vec
.chunks_exact(3) // режет на чанки без хвостов
// .chunks(3) // можно ещё так, но тогда паника будет
.for_each(|chunk| { // v вот тут
let [a,b,c] = chunk[..] else { panic!("Tail is too short") };
println!("{a} {b} {c}"); // 1 2 3
// 4 5 6
// panic
});
// массивы фиксированных размеров можно не spreadить, как вектора
// std::array вроде так не умеет
let [r,g,b] = int_to_vec3(0xFF_BB_AA);
println!("{r:X} {g:X} {b:X}"); // FF BB AA
// тут практически как в C++
// только по умолчанию оно будет value, а не ссылка
let [x, y] = Point{ x: 1, y: 2};
На любом языке можно написать такое, что будет компилироваться бесконечно долго.
Одна из двух главных болей в С++ - управление сборкой зависимостей и собственно время компиляции. Если компилировали что-то больше пары файлов на С++ и сталкивались с, например, CMake, то наверняка понимаете насколько в среднем дольше происходит сборка проекта с низкого старта - сидишь ручками прописываешь все кодген юниты, следишь за порядком включения .h файлов, следишь за тем, чтобы зависимости файла собирались раньше собственно зависимого, ради ускорения ещё и меняешь инструментарий с дефолтных компиляторных на всякие ccache/ninja/mold, иногда ещё и пребилд скрипты запускаешь, чтобы склеить маленький файлы в юниты побольше. А там ещё и фиче флаги не забыть в Cmake скормить, а то придётся переконфигурировать пол проекта и собирать их заново. Модули пока ещё в зайчатках, поэтому сжигая киловатт-часы процессорного времени в ожидании пока течёт мой кетчуп компилируется проект, приближаем тепловую смерть вселенной.
21/23 стандарт ещё не раскатали толком
Структурное связывание появилось в C++17.
плюс не все алгоритмы (пока?) красиво стыкуются в красивые пайплайны
Без конкретного примера непонятно, что имеется ввиду. Так-то всегда можно придумать пайплайн, куда какой-нибудь sort "из коробки" не подойдет.
Да и рэнжи нужно явно конструировать. В Rust они на уровне языка.
Так и в C++20 тоже на уровне языка. Либо я не понимаю, что такое "не на уровне языка" :-)
У плюсов отсутвует (пока?) возможность отбросить неиспользуемые биндинги
Ну просто пишется биндинг, но не используется. В каких-то очередных С++26 неиспользуемое поле можно будет написать символом подчеркивания. ИМХО, это всё какие-то не очень принципиальные мелочи.
связываем содержимое вектора с переменными
Кто мешает просто пользоваться ссылками на нужные элементы вектора? Ну да, не в одну строчку будет написано, но и только. Наверное, удобная фича, не спорю, но не сказать, что прямо жить без этого сложно, имхо.
Если компилировали что-то больше пары файлов на С++ и сталкивались с, например, CMake
Да, тут много сложностей бывает, согласен.
Всё это уже много раз на Хабре обсуждалось. Rust хорош тогда, когда не надо привязываться к куче уже написанного старого кода. Либо приходится связки с С++ городить. Тоже рабочий подход, не спорю. Каждый инструмент хорош, когда целесообразен в применении.
Без конкретного примера непонятно, что имеется ввиду.
Ближайшее, что вспомнил было вот это. Где-то видел ещё похожий рефакторинг, когда вместо пайплайна algo|algo|algo|algo
приходилось делать что-то вроде algo(algo(algo)|algo)|algo
. Некрасиво и поток мысли получается нелинейным. Но для некоторых алгоритмов это пока ещё просто не успели добавить, насколько мне известно (аналогично не все алгоритмы имеют constexrp версии). Есть библиотека, которая делает такие пайплайны более приближенные к ржавым.
Так и в C++20
В С++20 рэнжи есть в стандратной библиотеке, но не на уровне языка. Нельзя сделать for (auto i : 0..20)
, нужно явно вызывать адаптер std::iota
(не забыв про нюансы, которые пофиксят только в 26 стандарте), нельзя явно сослаться на слайс от контейнера а ля vec[4..10]
или как в питоне vec[4:10]
, нужно или опять же через iota
это делать, либо через std::span
. Это уровень стандартной библиотеки, а не уровень языка. Начни писать под какой-нибудь embed без неё, и удобного сахара остаётся не так много. Аналогичная история с std::tuple
- в расте достаточно просто явно указать свой кортеж (value1,value2)
и либо также дестрктурировать в переменные, либо через var.0/.1/.n
обращаться - в отличе от std::get<n>
в плюсах.
Ну просто пишется биндинг, но не используется
Ворнинги так и будут висеть, пока их каким-нибудь (void)_;
не заткнёшь. Ну и если у тебя в одном скоупе несколько разных биндингов, то они вполне могут конфликтовать всячески. В 26 пока обещают прочерки только для сопоставления с образцом, насколько мне известно, в остальные места оно не факт что попало.
Наверное, удобная фича, не спорю, но не сказать, что прямо жить без этого сложно, имхо.
Собственно, речь шла за отличия с плюсами, ни больше ни меньше. В общем жить без этого можно, но когнитивная нагрузка утекает на парсинг всех этих конструкций, которую теоретически можно было бы потратить на что-то чуть более полезное - думы за именование переменных, время жизни, производительность и прочее. cppfront кстати тоже про это.
Посмотрел и понял - Rust это сборная солянка из разных языков )
рэнжи, оператор as, синтаксис передачи параметров в функции явно из Паскаля.
let из Javasript, остальное из С/С++
У раста есть преимущество: ему не нужно сохранять совместимость с кодом 30-40-летней давности. Правда, создатели раста иногда умудряются в новых версиях терять совместимость с предыдущей. Всё же для блага делается, а программисты не переломятся, переделают код, который уже работал.
Так практически любой современный язык - это сборная солянка из практик последних полвека программирования.
let из Javasript
он НЕ из javascript. В js это костыль для локальности переменных. В Rust он появился под влиянием OCaml (исходный компилятор на нём был).
Хвосты остальных фишек можно найти едва ли не в какой-нибудь Ada.
Нельзя сделать
for (auto i : 0..20)
Ну нельзя, но чем так уж плох for (int i =... ? Тем более, как Rust сам понимает, какой здесь тип у i? Может, я хочу, чтобы был uint8_t i? Например, мне в одном проекте для Arduino пришлось по максимуму экономить память, я везде, где мог, сокращал переменные с int до byte.
либо через
std::span
Это чем-то плохо?
уровень стандартной библиотеки, а не уровень языка. Начни писать под какой-нибудь embed без неё, и удобного сахара остаётся не так много.
А на расте можно прямо под любой эмбед писать?
в расте достаточно просто явно указать свой кортеж
(value1,value2)
Так и в плюсах вроде можно: {"ABC", 25, 36.1}
отличе от
std::get<n>
В докладе Антона Полухина рассказывается, что кортежами они в Яндексе предпочитают не пользоваться, по крайней мере, не рекомендуется их возвращать из функций. Через какое-то время сам забудешь, что в кортеже из 10 элементов возвращается. Ну это так, к слову.
Если честно, для себя не могу придумать, когда бы мне через связывание приходилось обращаться к элементам вектора. Зачем?
какой здесь тип у i
ну, вот кстати ещё один неупомянутый плюс - продвинутая дедукция типов.
Может, я хочу, чтобы был uint8_t i
Для 8битных числел просто явно укажите его: 0_u8..20
.
Это чем-то плохо?
большая вербозность, больше кодогенерации, дольше компиляция, про no std уже писал выше.
А на расте можно прямо под любой эмбед писать?
Официально есть 3 уровня поддержки языком всяких архитектур. Там и риски всякие и esp и чего только нет - бэкэнд llvm в принципе многое умеет. Так что да, можно под многое писать. Про поддержку языка в ядре линукса наверняка тоже слышали. Есть FAQ-гайд про встроенку, есть еженедельник. Так что да, практически любая встроенка покрыта. Есть даже отдельные проекты чтобы писать на расте под древние архитектуры - morotolla 68k, gameboy, вроде под девайсы amiga тоже что-то было. На одном из докладов на первых конференциях была история про то что ржавчина уже и в кубсатах каких-то там в космосе работала.
Так и в плюсах вроде можно: {"ABC", 25, 36.1}
Только если где-то явно указан тип, в сигнатуре функции или в типе переменной. Не уверен что завезли автоматический вывод шаблонов в 17 стандарте для кортежей, так что в любом случае получается довольно вербозно. Без сигнатуры плюсы не смогут догадаться, конструируется там std::tuple
или какой-нибудь struct Foo
.
Через какое-то время сам забудешь, что в кортеже из 10 элементов возвращается
Для C++ - верно говорит. Проще сделать небольшую структурку, что в аргументы, что в возвращаемые значения. Для Rust это тоже в какой-то мере имеет смысл, но существуют паттерны, когда с ними работать проще. Самый простой пример работы с кортежами - нумерация элементов в цикле.
for (i, v) in (0..10).step_by(2).enumerate() {
println!("{i} {v}");
}
плюсовый std::view::enumerate
делает что-то похожее, но там структурка похоже генерируется.
Если честно, для себя не могу придумать, когда бы мне через связывание приходилось обращаться к элементам вектора
Не сказать, чтобы паттерн сильно распространён и многие по старинке делают let my_var = vec[0];
. Чтение csv, или парсинг формата 3д объектов, где кучка треугольников подряд указаны. Лично использовал для обработки отчётов о покрытии кода от lcov, например. Там записи были в формате
file1 1234 1234 100.0% 1234 1234 100.0% 1234 1234 100.0%
file2 3412 3412 100.0% 3412 3412 100.0% 3412 3412 100.0%
И обработка одной записи превщалась во что-то типа
let values : Vec<&str> = line?
.split(" ")
.filter(|word| !word.is_empty())
.collect();
let [filename
, total_fn, cover_fn, _ // покрытие по функциям
, total_bl, cover_bl, _ // покрытие по блокам
, total_ln, cover_ln, _ // покрытие по линиям
] = values[..] else { panic!() };
большая вербозность, больше кодогенерации, дольше
Про время компиляции - Вы прямо измеряли и сравнивали?
Про поддержку языка в ядре линукса наверняка тоже слышали
Что-то слышал, но что это значит? Встроенный компилятор раста в линуксе сразу есть? А кто его мешает установить, если его ещё нет?
Только если где-то явно указан тип, в сигнатуре функции или в типе переменной
Нет, можно сразу написать:
std::tuple tp { 10, 20, 3.14, 42, "hello"};
Самый простой пример работы с кортежами - нумерация элементов в цикле.
Придумать можно много чего. Пытаюсь вспомнить, где бы мне такое было нужно хоть раз.
Чтение csv, или парсинг формата 3д объектов, где кучка треугольников подряд указаны.
Кстати, насчет 3D. Хоть одна серьёзная библиотека для 3D на расте есть? Как Unreal Engine, например? Ну или вот CUDA. Которую, конечно, хоть из Питона вызвать можно через соответствующую обёртку.
Слышал, что в расте периодически в очередной версии частично теряют совместимость с предыдущей. Что-то мне подсказывает, что пока такое не прекратится, разработчикам больших и серьёзных библиотек не очень захочется связываться с таким языком. Может, я и ошибаюсь - поправьте меня.
Про время компиляции - Вы прямо измеряли и сравнивали?
Писал шаблоны, которые значимо тормозили компиляцию. Конкретно tuple не мерял.
Что-то слышал, но что это значит?
Это значит, что вполне существует возможность писать драйверы на Rust, что в среднем также смахивает на программирование под embed по требованиям, учитывая количество девайсов которые запускают тот линукс.
Встроенный компилятор раста в линуксе сразу есть
В какие-то дистры завезли. В голом дебиане вроде по-умолчанию пока нет, но я за дистрами не слежу, поэтому детальнее не расскажу.
Кстати, насчет 3D
Gamedev на расте есть. Сопутствующие библиотеки на для всякого разного соотвественно имеются. В том числе чтобы это дело собиралось в веб под wasm. Есть целый сайт про инфраструктуру - математика, физика, звуки, всякие компонентные системы, интеграции, поддержка форматов текстур/звуков/моделей. Можете глянуть Bevy и Fyrox, например. Даже более того - есть энтузиасты, которые занимаются всякой тяжелой распределённой вычислиловой посредством BLAS, включая всякий ML, нейронки и что угодно вычислимое на GPU. Учитывая что с релиза 1.0 прошло почти 10 лет основные хотелки почти наверняка успели покрыться.
Слышал, что в расте периодически в очередной версии частично теряют совместимость с предыдущей.
На уровне языка - таких проблем нет. На уровне библиотек - есть MSRV и семантическое версионирование.
Насколько в целом экосистема взрослая/стабильная вопрос отдельный, и зависит от того что вы хотите. Что-то намеренно стабилизировали чтобы выпустить 1.0 библиотеки, что-то так и осталось в 0.х.х версии, хотя вполне может быть зависимостью ещё миллиона другого крейтов. Каких-то принципиальных вещей с этим связанных, которые могли бы остановить людей от использования в новом коде я не вижу.
Писал шаблоны, которые значимо тормозили компиляцию. Конкретно tuple не мерял.
Лет 20 назад шаблоны тормозили компиляцию куда сильнее, чем сейчас. Всё это относительно.
Это значит, что вполне существует возможность писать драйверы на Rust
Их можно до сих пор хоть на ассемблере писать. Вопрос в целесообразности. Раст - он для того, чтобы было проще писать? ИМХО, писателям драйверов простота особо не нужна.
Gamedev на расте есть
Звучит не совсем как "почти весь геймдев пишется на..."
Энтузиасты и взрослость системы - это хорошо, но что-то мне подсказывает, что доля серьезного коммерческого софта на расте невысока. Недавно в комментариях к очередной статье про Rust vs C++ это обсуждалось, там так никто и не смог толком привести пример какого-то массового софта на расте. Ну вот я знаю, что приложение Bolt, аналогичное Яндекс.Такси, написано на Go. На расте что-то такое есть?
что приложение Bolt, аналогичное Яндекс.Такси, написано на Go
Бэкэнды Discord и Cloudflare можно считать достаточно массовым? Или виртуалки на амазоне? Процентов 20 firefox переписано на Rust, при условном 1% рынка занятого браузером и глобальном проникновении интернета порядка 60% (от 8 млрд), получается тоже немаленькая циферка. Это не считая, что библиотеки, которые были переписаны в рамках оксидации являются зависимостями ещё кучи других приложений, по касательной покрывая некоторый процент от линуксовых десктопов. Разрабы довольно массово ставят такие штуки как ripgrep (даже есть в дистрах по-умолчанию), fd-find и gitui.
Не до конца понимаю, по какому критерию считать массовость софта.
Какова доля этих виртуалок на Амазоне?
В общем, все эти "один процент" и "некоторая доля от" непохожи на "массовое проникновение".
Про виртуалки я особо ничего не знаю - они блогов по теме не пишут и сфера применения тех виртуалок для меня непонятна - ни то bare metal docker, ни то аналог kvm какой-то. При скейле амазона тем не менее цифры использования наверняка уже перевалил за миллионы инстансов.
Cloudflare более словоохоч и про их оржавение известно более подробно. Та pignora за условные полгода с анонса и до опенсорса покрыла больше миллиарда сетевых запросов. А там помимо неё под организацией ещё 50+ ржавых реп которые как-то участвуют во всей этой инфраструктуре и на несколько лет старше пиньйоры.
В общем, все эти "один процент" и "некоторая доля от" непохожи на "массовое проникновение".
Собственно об этом и написал в финале - дайте критерий по которым можно было бы определять массовость.
У приведённого Bolt клиентура насколько я понимаю работает только в пределах Эстонии и Go присутвтует только на бэкэнде в виде микросервисов (ибо кому в здравом уме придёт писать на нём под ios/android). Даже если представить что все полтора ляма эстонцев пользуются этим ежедневно, то та же pignora в несколько раз перекроет количество обрабатываемых данных которые потенциально могут быть у Bolt.
The company is headquartered in Tallinn and operates in over 500 cities in more than 45 countries in Europe, Africa, Western Asia and Latin America. The company has more than 150 million customers and more than 3 million driver and courier partners.
Непохоже, что это всё один серверок в Таллинне обслуживает, и пользуются этим только полтора ляма эстонцев.
дайте критерий по которым можно было бы определять массовость
Ну не знаю. Сколько всего существует игровых движков, сколько из них написаны на C++, а сколько на Rust? Аналогично можно и про другие сферы порассуждать.
Непохоже, что это всё один серверок в Таллинне обслуживает, и пользуются этим только полтора ляма эстонцев.
Дальше гугла не смотрел, про кампанию ничего не слышал. Оценки можно откалибровать, если есть какая-то детальная информация об их инфраструктуре.
Сколько всего существует игровых движков, сколько из них написаны на C++, а сколько на Rust
Тут опять же возникает вопрос - что считать за игровой движок? Должно ли оно включать полный цикл игровой разработки от создания ассетов, редактора сцен, скриптования, работы со звуком/видео/'эффектами и прочее в том же духе вполдь да бандлинга и публикации в сторы бинарей? Если кто-то соберёт это из разных библиотек, можно ли это считать за игровой движок? Или игнорируем из чего игра сделана и считаем sloc по языкам для конкретных игр? raylib, cocos2d-x, godot, unreal-engine - кто фреймворк, а кто уже смешарик? Выше кидал ссылку на ржавую gamedev инфраструктуру - что из этого принимает за игровой движок?
Второй момент - делаем ли мы нормализацию наших данных по времени: релиз Rust 1.0 был в 2015, С++ появился на бодрых 30 лет раньше, отсекаем ли мы тогда код древнее 2015? или может берём отсечку по 11/17 стандарту? С момента появления UE?
Критерии, Билли, мне нужны критерии.
что считать за игровой движок
Что-нибудь вроде этого, например:
Самые популярные бесплатные движки для разработки игр / Хабр (habr.com)
Игровые движки, которые на слуху / Хабр (habr.com)
Какой игровой движок выбрать? / Хабр (habr.com)
Недавно еще была статья на Хабре, где геймдевелопер штук 50-60 движков обозревал, сходу не помню, как называется.
делаем ли мы нормализацию наших данных по времени: релиз Rust 1.0 был в 2015, С++ появился на бодрых 30 лет раньше, отсекаем ли мы тогда код древнее 2015?
А зачем отсекать? Да, C++ появился раньше, ну так это тоже один из его плюсов - за много лет и в языке наработано много, и на нем создано тоже много чего.
Критерии, Билли, мне нужны критерии.
Вот что мне точно не нужно - пустые споры. Было бы желание, информацию найти можно.
Ссылки по теме кидал выше по тому же геймдеву. Движки есть, фремворкики есть, биндинги есть, библиотеки есть. Каких-то заметных игр не сильно много и они обычно написаны на самодельных закрытых движках, не open source - считайте меряйте.
Вот что мне точно не нужно - пустые споры.
Тогда непонятно что же вы пытаетесь узнать. Bolt на 150 лямов пользователей у вас массовый, а Cloudflare, обслуживающий едва ли не треть интернета у вас "не похож на массовый". В таком случае считаю, что все эти вопросы обычным троллингом.
Мне интересно другое. Можно ли написать данную программу полностью на Rust, без использования C++?
Видимо, без CUDA можно.
А с CUDA?
Не знаю. Вроде есть вот такое для rust:
RustaCUDA — Rust gfx library // Lib.rs
Возникает вопрос, знает ли об этом автор статьи.
del
Вопрос к автору статьи: почему бы не попытаться вообще от C++ избавиться в этой программе? Вроде как, есть библиотеки для работы с CUDA на Rust:
Вы посмотрите когда в эту библиотеку последний раз коммит был.
Она совсем не позволяет решить поставленную задачу?
Зачем тратить время на изучение заброшенных библиотек?
Рисуем фракталы на Rust и CUDA