Справжні вбивці С++

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

Всім привіт! Я Саша Каленюк. Останні сім років я працюю на компанію Матеріалайз, де ми разом із командою алгоритмістів пишемо крутезну біблотеку для 3D-друку. В цілому, переважно на С++ я пишу вже майже сімнадцять років і майже сімнадцять років намагаюсь позбутися цієї шкідливої звички.

Все почалося у 2005 році з рушія для космічного симулятора. Було в цьому рушієві все, що в 2005 році було в С++. І асемблерні вставки, і тризірковий код, і вісім шарів наслідування. Макроси ще були. Ітератори усюди, як заповідав Степанов, і метакод, як навчав Алекснадреску. Все було. Не було тільки відповіді на найголовніше питання: навіщо туди все це напхали?

Втім, згодом навіть і на це питаня відповідь знайшлася. Виявилось, що код цей до мене писали вже вісім років. І п’ять різних команд. Кожна нова команда заходила на проект, обкладала матюками попередників, брала за основу свіжу моду в світі С++ і загортала попередній код у новий, додаючи при тому не більше ніж 10-20 мілікармаків функціоналу.

Спершу я намагався якось розібратися в усьому тому зоопарку, робив якісь таски, щось правив. В принципі, якось косо-криво, але виходило. А потім мене спитали: «Не хочеш попереписувати шейдерний код з асемблера на GLSL?» Я подумав, чорт його знає, що то за GLSL, але гірше за С++ не буде, і сказав, що хочу. Гірше не стало.

Так і повелося. Щоразу, як треба було щось написати не на плюсах, я казав, що хочу, і писав. Писав на чистому Сі, на MASM32, на C#, на PHP, Delphi, ActionScript, JavaScript, Erlang, Python, Haskell, D, Rust, навіть для InstallShield якісь скрипти писав. I на VisualBasic для екселя, і на bash, а на додачу і ще на декількох пропрієтарних мовах, про які навіть розповідати не можу. Навіть колись було діло, робив власну мову для скриптування 2D-квестів, хоча фактично саму граматику створював гейм-дизайнер, я просто перетворював його забаганки на робочий продукт.

І так вже майже сімнадцять років. Пробую щось нове, але щоразу повертаюсь до С++, при тому вважаю, що відважувати молоде покоління від цього жахливого створіння комітету — це моральний обов’язок досвідчених програмістів, які вже втратили пів життя на перемовини з його компіляторами. Так само як, наприклад, відваджувати спортивну молодь від паління є моральним обов’язком тих, хто вже помирає від раку легенів.

Тож в чому справа? Звідки цей стокгольмський синдром? А справа в тому, що жодна з мов, особливо з так званих «вбивць С++», тобто тих, які створювались, щоб цю С++ замістити, жодної справді важливої переваги над С++ у сучасному світі не надає. Здебільшого, всі нові ідеї у комп’ютерному мовознавстві зводяться до того, щоб тримати програміста за руку, щоб він біди не накоїв. Що непогано, але створювати якомога більше продукту якомога менш кваліфікованою силою — це проблематика двадцятого, а не двадцять першого сторіччя. Хмарні обчислення все перевернули з голови на ноги.

В двадцятому сторіччі як було? Маєш ідею, загортаєш її у юайку, продаєш як десктопний продукт. Продукт лагає — не страшно, за два роки коп’ютери підростуть, тоді не лагатиме. Головне — якнайшвидше вийти на ринок, наробити фічей і бажано одразу без багів. І отут так, якщо компілятор не дає програмістам наробити багів — то це, очевидно, дуже круто і економічно вигідно, бо інакше ти платиш програмістам за час, який вони витрачають на баги замість фічей.

Тепер не так. Маєш ідею — загортаєш її в апішку і підіймаєш в клауді. Тобі платять не за диск із програмою, а тільки за корисну роботу, яку вона робить. А за те, що в тебе щось лагає, тепер платить не умовний Гордон Мур зі своїм легислативним аппаратом, а ти сам. Буквально сплачуєш рахунки умовному амазону за власну безумовну неефективність.

І раптом виявляється, що жоден вбивця С++, навіть ті, які я щиро люблю і поважаю, на кшалт D, Rust, і Julia, не допомагає вирішити головну проблему двадцать першого сторіччя. Вони не допомагають тобі писати швидкий і економний код. Ну, принаймні код швидший і економніший, ніж на С++. Вони всі занадто однакові, щоб давати якісь суттєві переваги одне перед одним. Rust, Julia, Clang навіть використовують один і той самий бекенд. Не можна виграти автоперегони, якщо їдеш до фінішу тим самим автобусом, що і решта учасників.

А в нашому з вами спільному становищі, економний код — це не тільки менші рахунки, а ще і менші відчислення на російську воєнщину. Бо чиїм газом харчуються станції, що живлять датацентри в Дюсельдорфі і Франкфурті, ми ж всі розуміємо.

То що ж тоді допомагає вирішувати головну проблему двадцять першого сторіччя, якщо не новомодні мови програмування? А от про це зараз ми і поговоримо.

Вбивця 1. Spiral

Давайте перевіримо, як працює ваша інтуіція. Що працює швидше, стандартна функція сінуса чи його поліноміальна модель?

auto y = std::sin(x);
 
// vs.
 
y = -0.000182690409228785*x*x*x*x*x*x*x
	+0.00830460224186793*x*x*x*x*x
	-0.166651012143690*x*x*x
	+x;

Друге питання, що швидше: використувати стандартні логічні операції для порівняння з однобітним значенням чи піти на переступ і забабахати арифметичну мікрооптимізацію?

if (xs[i] == 1 && xs[i+1] == 1 && xs[i+2] == 1 && xs[i+3] == 1)
 
// vs.
 
inline int sq(int x) {
  return x*x;
}
 
if(sq(xs[i] - 1) + sq(xs[i+1] - 1) + sq(xs[i+2] - 1) + sq(xs[i+3] - 1) == 0)

Ну і наостанок, що краще для сортування триплетів даблів: своп-сорт чи індекс-сорт?

if(s[0] > s[1])
  	swap(s[0], s[1]);
	if(s[1] > s[2])
  	swap(s[1], s[2]);
	if(s[0] > s[1])
  	swap(s[0], s[1]);
 
// vs.
 
	const auto a = s[0];
	const auto b = s[1];
	const auto c = s[2];
	s[int(a > b) + int(a > c)] = a;
	s[int(b >= a) + int(b > c)] = b;
	s[int(c >= a) + int(c >= b)] = c;

Якщо ви швидко і однозначно видповіли на всі питання, то інтуіція в вас працює препогано. Зовсім не відчуваєте засадки. Жодне питання такого штибу не має однозначної відповіді без чітко зазначеного контексту. А мої питання — так і подавно.

Яка машина виконуватиме код? Який компілятор його збиратиме? Які налаштування компілятора? Лише знаючи все це, можна пробувати прогнозувати, а краще навіть не пробувати, а міряти швидкодію кожного конкретного рішення.

У випадку першого питання, поліноміальна модель працює в три рази швидше за стандартний синус, якщо запускати її на Intel® Core™ i7-9700F CPU @ 3.00GHz; і збирати компілятором clang 11, із флагами -O2 -std=c++14 -march=native.

Але якщо її же запускати на GeForce GTX 1050 Ti Mobile збираючи nvcc з флагом —use_fast_math, то стандартний синус буде в десять разів швидшим за модель! Модель, звісно, можна значно пришвидшити: позбутися даблів і завернути схемою Горнера, але навіть так беззаперечної переваги над стандартним синусом не отримати.

Наступне питання теж однозначної відповіді не має. На вищезгаданому Інтелі, арифметична мікрооптимізація має сенс і, мабуть, навіть право на життя. Вона пришвишує код в два рази. Але на ARMv7 з аналогічним компілятором і флагами, стандартні логічні операції переганяють мікрооптимізацію на 25%.

І третє — так само. На Інтелі в три рази швидше індекс-сорт, на Джі-форсі — теж в три рази, але своп-сорт.

Отже, всі наші мікрооптимізації, які ми так любимо, можуть давати виграш, а можуть і програш. Було б чудово, якби компілятор міг підкладати те чи інше рішення в залежності від того, що було б вигідніше саме зараз. Але він такого робити не буде. Я спеціально підібрав приклади, де компілятору для прийняття правильного рішення не вистачає певних спеціальних знань.

У першому прикладі компілятор не тільки не знає, що вказаний поліном має наближувати синус, а навіть не знає, чи дозволяється нам та втрата точності, яка йде довіском з таким наближенням. У С++ немає способу розслабити вимоги до точності, окрім як флагом на кшалт —use_vsrata_math і то на рівні об’єкту трансляції, і то без жодної конкретики.

У другому прикладі, компілятор не знає, що ми порівнюємо саме нулики-одинички, а не справжні інти, отже він в принципі не має права використовувати запропоновану мікрооптимізацію. А ми не можемо ніяк йому наші наміри підказати.

У третьому прикладі компілятор міг би здогадатися підставити вигідне сортування, так, насправді, std::sort теж знає, коли використовувати мердж-сорт, а коли квік. Але обидва рішення розписані сильно детально, аби компілятор міг розпізнати їх як сортувалки.

І тут ми підходимо до Spiral. Це спільний проєкт університету Карнегі Мелон і Федеральної вищої технічноїї школи Цюріха. Якщо в двох реченнях: спеціалістів з обробки цифрових сигналів задовбало переоптимізовувати вручну свої улюблені алгоритми на кожну нову залізяку, тож вони написали програму, яка робить цю марудну роботу за них. Програма приймає на вхід високорівневий опис алгоритма і, що важливо, детальний опис архітектури залізяки, під яку їй треба оптимізовувати, і оптимізовує.

Важливий момент. Оптимізовує, тобто оптимізує в суто математичному сенсі. Шукає глобальний оптимум у спільному факторному просторі інваріантів алгоритму і архітектурних обмежень цільового обчислювального пристрою. Це те, що компілятори не вміють робити в принципі. Компілятор не шукає оптимального рішення, він використовує евристики, яких його навчили розробники, щоб робити результуючий код швидше, а це не те саме. Компілятор, замість того, щоб використовувати сильні сторони машини і робити математичний пошук оптимума, емулює програміста на асемблері. Ну, хороший компілятор емулює хорошого програміста, і на тому спасибі.

Spiral — проєкт дослідницький, обмежений за бюджетом і за напрямком діяльності. Але результати показує вражаючі. Так, на швидкому перетворені Фур’є, їхнє оптимізоване рішення більш ніж в два рази обганяє і версію MKL, і FFTW. На Інтелі. Щоб було легше сприймати масштаб перемоги MKL — це Math Kernel Library від самого Intel, тобто від компанії, яка найкраще в світі знається на мікрооптимізаціях під власну архітектуру. А FFTW, яку ще часто розшифровують як «Fastest Fourier Transform in the West», — вузкоспеціалізована бібліотека від людей, які найкраще в світі знаються саме на перетворенні Фур’є.

Коли технологію остаточно комерціалізують, постраждає не тільки С++, а і Rust, і Julia. Навіть шановному професорові Фортранові стане непереливки. Навіщо потрібен С++, якщо можна створювати алгоримти мовою високого рівня, а працюватимуть вони в два рази швидше, ніж якби вони були написані на С++?

Вбивця 2. Numba

Найкраща в світі мова — це мова, яку ти вже знаєш. Доволі довго цією мовою для більшості програмістів у всествіті була Сі. Що, до речі, пояснює, чому багато років поспіль Сі очолював індекс TIOBE за популярністю, а разом з ним в п’ятірці лідерів тусувалися сіподібні С#, Java і С++. Але минулого року сталося нечуване! Сі скинули з п’єдестала.

Мовою-вискочкою, мовою-іконокластом став Python, або «Пітон» українською. Він нарощував свою популярність декадами, повільно, але безупинно. Ставав мовою року у 2007, 2010, 2018, 2020 і 2021 роках. Для порівняння: С++ була мовою року за версією TIOBE у 2003 році, і все. Це був її перший і останній раз.

«Але ж Пітон повільний!», — скажете ви, і будете термінологічно неправі. Мова не може бути повільною, як не може бути повільним, наприклад, баян. Як швидкість баяна залежить від того, хто на ньому грає, так і «швидкість мови» залежить від ефективності компілятора.

«Але ж Пітон не компілює!», — заперечите ви, і знову сядете у калюжу. Я і не казав, що компілювати має саме Пітон. Дозвольте проілюструвати.

Був у мене проєкт. Алгоритм симуляції 3D-друку, який ми написали спершу на Пітоні, потім переписали на С++, бо «Пітон же повільний», потім портували на GPU, а потім підключився я і місяць займався тільки тим, що налаштовував білд під Лінукс, валідував непітонівські імплементації пітонівською, мікрооптимізовував код під Tesla M60, бо з того, що надавав клауд-провайдер, саме у цій картці було найліпше співвідношення ціни аренди і швидкодії. Коротше, займався всім чим завгодно, але не власне алгоритмом.

А трохи згодом дзвонить мені студент, якого у нас в Бремені взяли на підробіток, і питає: «Кажуть, ти знаєшся на гетерогенщині, допоможи експериментальний алгоритм на GPU розпаралелити?». Ха! Ну я йому почав розказувати за CUDA, за CMake, за білд на Лінукс, за тести, за оптимізацію, розказував ледь не довше, ніж розбирався. Він вислухав дуже ввічливо всю цю ахінею, німець все-таки, хоча сам з Непалу, але наприкінці спитав: «Це все дуже цікаво, дякую, але я от в Пітоні перед функцією пишу @cuda.jit, а воно мені щось про масиви каже і не заводиться. Що то може бути?».

Я не підказав. Не знав. Втім, він сам розібрався, виявилось, що він замість масивів NumPy передав штатні пітонівські листи, а Numba з ними дійсно не заводиться. Розібрався і за кілька днів розпаралелив свій алгоритм. Під GPU. На Пітоні. Хочеш запускати на Лінуксі — будь ласка! Хочеш валідувати пітонівською імплементацією — так це вона і є! Хочеш оптимізувати під M60 — Numba збере код найоптимальніше саме під ту архітектуру, на якій запускатиметься алгоритм, бо в неї Just-in-time компілятор.

Отакої! Виявляється, що я, старий хрест-хрестоносець, згаяв місяць часу незрозуміло на що, а студент-пітоніст зробив мій обсяг работи за два-три дні. І тільки тому не за півгодини, що в перший раз паралелив із Numba. Та що ж то за Numba така? У чому магія?

Жодної магії. Просто пітонівські декоратори перетворюють будь-який пітонівський код на абстратне синтаксичне дерево. Що хочеш з тим деревом — те і роби. Numba — це така пітонівська бібліотека, яка хоче компілювати твій код будь-яким бекендом і під будь-яку платформу. Хочеш масивного паралелизму на інтелівському CPU — всі принади LLVM в твоєму розпоряджені. Хочеш того самого на нвідійвській GPU — будь-ласка, Numba вміє в CUDA.

@cuda.jit
def matmul(A, B, C):
	"""Perform square matrix multiplication of C = A * B."""
	i, j = cuda.grid(2)
	if i < C.shape[0] and j < C.shape[1]:
    	tmp = 0.
    	for k in range(A.shape[1]):
        	tmp += A[i, k] * B[k, j]
    	C[i, j] = tmp

От саме ця штука і здійснює компіляцію. Так, в теорії обігнати Numbою С++ не вийде, теоретична швидкодія в них однакова. Однаковий же бекенд. Але на практиці переваги JIT-компіляції все-таки себе показують. Був у нас випадок, коли, наприклад, ми переписували алгоритм із Пітона на С++ заради швидкості, а він став в три рази повільнішим, тому що через деяких конкретних клієнтів ми змушені були підтримувати бінарні релізи бібліотеки із допотопним SSE2.

Звісно, добре було б мати гарантовану перевагу, як у випадку Spiral. Але то все-таки ще дослідницький проєкт, його слава ще не настала. А Пітон разом із Numba досить впевнено, хоча і повільно, вбиває С++ прямо зараз, в режимі реального часу. Бо якщо ти можеш писати на Пітоні і мати швидкодію С++, то навіщо тобі С++?

Вбивця 3. ForwardCom

Давайте влаштуємо ще одну вікторину. Перед вами три фрагменти коду. Який з них, чи може які з них, написані на асемблері?

1.

invoke RegisterClassEx, addr wc    	; register our window class
    invoke CreateWindowEx,NULL,
    	ADDR ClassName, ADDR AppName,\
    	WS_OVERLAPPEDWINDOW,\
    	CW_USEDEFAULT, CW_USEDEFAULT,\
    	CW_USEDEFAULT, CW_USEDEFAULT,\
    	NULL, NULL, hInst, NULL
	mov   hwnd,eax
	invoke ShowWindow, hwnd,CmdShow    	; display our window on desktop
    invoke UpdateWindow, hwnd          	; refresh the client area
 
	.while TRUE                        	; Enter message loop
                invoke GetMessage, ADDR msg,NULL,0,0
            	.break .if (!eax)
            	invoke TranslateMessage, ADDR msg
            	invoke DispatchMessage, ADDR msg
   .endw

2.

(module
  (func $add (param $lhs i32) (param $rhs i32) (result i32)
	get_local $lhs
	get_local $rhs
	i32.add)
  (export "add" (func $add))
)

3.

v0 = my_vector          	// we want the horizontal sum of this
int64 r0 = get_len ( v0 )
int64 r0 = round_u2 ( r0 )
float v0 = set_len ( r0 , v0 )
while ( uint64 r0 > 4) {
    	uint64 r0 >>= 1
    	float v1 = shift_reduce ( r0 , v0 )
    	float v0 = v1 + v0
}

Якщо ви відповіли, що всі три, вітаю! Ваша інтуіція значно покращилась!

Перший написаний на MASM32. Це макроасемблер із «іфами» і «вайлами», на якому пишуться нативні програми для Windows. Так, навіть не «писалися», а «пишуться». Micosoft дуже шанобливо ставиться до зворотної сумісності, і програми, написані під Win32 API, прекрасно почуваються на сучасних машинах.

Це навіть дещо іронічно. Сі створювався через потребу переносити код UNIX із PDP-7 на PDP-11. Це була мова, яка мала б стати портабельним асемблером, здатним пережити бурхливий розвиток комп’ютерної архітектури семидесятих. Але в двадцять першому сторіччі цей розвиток настільки сповільнився і видохся, що програми на MASM32, які я писав ще на першій роботі, прекрасно збираються і працюють по сьогодні, а от впевненості, що бібліотека, яка ще в минулому році збиралася із CMake 3.18, збереться без жодної запинки із CMake 3.23, в мене ніколи немає.

Другий фрагмент — це Web Assembly. Це навіть не макроасемблер, себто жодних «іфів» і «вайлів» в ньому немає, а радше людиночитабельний код для віртуалної машини всередині вашого браузера. Або навіть не вашого. Будь-якого бразуера.

Тобто код на Web Assembly в принципі не залежить від архітектури вашої залізяки. Цей код абстракний, універсальний, всеядний, називайте як хочете.

Третій фрагмент — найцікавіший. Це ForwardCom — пропозиція асемблера, яку висунув Агнер Фог, вельмивідомий автор мануалів з оптимізації як програм на С++, так і асемблерного коду.

Як із Wasm, wе теж пропозиція навіть не стільки асемблера, скільки універсального набору інструкцій, створеного, аби уможливити навіть не зворотню, а попередню сумісність. Справжнє ім’я ForwardCom — an open forward-compatible instruction set architecture. Іншими словами, це пропозиція мирного договору.

Всі ми знаємо, що найпоширеніші архітектури: x64, ARM і RISC-V мають різні набори інструкцій. Але ніхто не знає гідної причини, чому це так має лишатися. Бо всі сучасні процесори, за винятком, можливо, найпростіших для мікроконтролерів, виконують не код, який їм дають програмісти, а мікрокод, який вони самі видобувають із запропонованого потоку інструкцій. Іншими словами, не тільки M1, а кожен процесор має транслюючий шар для зворотньої сумісності.

І що ж заважає зробити такий самий шар, але для сумісності попередньої? Окрім конфліктуючих амбіцій конкуруючих компаній, абсолютно нічого. Якщо компанії зможуть домовитися між собою, замість того щоб писати шари сумісності для всіх підряд архітектур, ForwardCom поверне програмування на асемблері у мейнстрім. Адже цей шар попередньої сумісності дозволив би прибрати найкритичніший невроз будь-якого програміста на асемблері: «А що, якщо я напишу офігенний код, такий, який випадає написати лише раз на життя, а процессор хоба — і раптом застаріє?»

От із цим шаром — не застаріє.

Ще розвиток програмування на асемблері стримує міф про те, що це дуже складно і через те — непотрібно. Знову таки, пропозиція Фога адресує і цю проблему. Якщо люди вважають, що на асемблері писати складно, а на Сі чомусь легко, хай асемблер буде схожий на Сі. Жодних проблем. Немає жодної поважної причини, з якої сучасний асебмлер мав би виглядати так само, як його прадід в п’ятидесятих.

Ви тільки що самі бачили три зразка асемблера. Жоден з них на «класичний» асемблер не схожий, і не має бути схожий.

Отже, ForwardCom — це асемблер, на якому можна писати теоретично оптимальний нестаріючий код, і який не змушує програміста вчити асемблер в «класичному» розумінні. Тільки машинну архітектуру. У всіх сенсах, це Сі, такий яким він мав би бути.

Якщо вам не вистачає Сі, і хочеться інкапсуляції, наслідування, поліморфізму, ця свята трійця імплементована на TASM, починаючи з четвертої версії. Статичного поліморфізму хочеться — знову таки, типова задача для макроасемблера. Якщо є набор інструкції, прикрутити туди якусь макросистему — справа не архіскладна.

І якщо все це можна мати без С++, то навіщо тоді С++? Хіба що, щоб було, коли шпілите у футбол, поки проєкт білдиться.

Отже, коли все-таки здохне С++

Ми живемо в постмодернову епоху. Ніщо не вмирає, окрім людей. Як не вмерла латина, або не помер COBOL, так і С++ приречена на довічне існування між життям і смертю. С++ остаточно ніколи не здохне, нові технології просто витискатимуть її із мейнстрима на маргінес. Хоча чому власне «витискатимуть»? «Витискають».

Вже зараз моя робота як програміста на С++ починається з Пітона. Я складаю рівняння в SymPy, він їх символьно розв’язує і перетворює на код. Потім я вставляю нагенерований код в С++ навіть не фоматуючи, бо форматом опікується clang-tidy. Потім компіяція, потім тести, потім профайлінг. Останні оптимізації, як данстист під мікроскопом, я роблю не тільки під тестами, а і під дізасемблером, бо інакше доводиться забагато чого вгадувати, а це шкідливо для фантазії.

Якщо поміняти С++ на «не С++», робота моя на 80% лишиться такою самою. Тож може С++ вже на 80% помер?

Сподобалась стаття? Натискай «Подобається» внизу. Це допоможе автору виграти подарунок у програмі #ПишуНаDOU

👍ПодобаєтьсяСподобалось43
До обраногоВ обраному7
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Стаття просто вогонь!

C живіше за усіх живих, чому тоді C++ має помирати?

Так, живіше за усіх живих
Але час іде, і вже треба винести з мавзолею та поховати по-людьски.

Також C та С++ -дуже різні мови, якщо ви не у курсі.

Micosoft дуже шанобливо ставиться до зворотної сумісності, і програми, написані під Win32 API, прекрасно почуваються на сучасних машинах.

Спірно, дуже спірно, воно може і працює, але все в артефактах.

Я что-то не понял, автор ещё ничего не писал на Golang? Зря всю жизнь прожил.

Якщо без тролінгу, то гошечка не є заміною плюсам, вона грає на полі, де грають java та .net

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

мультипоточность из коробки

Это которая «green threads»? Такая себе мультипоточность...

фу, це ж тупе С

Именно. И не просто «тупе С», а исконный благословенный POSIX.

і де ж тут убивця цепепе?
де синтетичний цукор?
воно не ням-ням

і де ж тут убився цепепе?

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

Что там за адский трэш, внутри ентого «std::async» под капотом?

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

токіо транслюється в треди, чи в FSM?
std::asynct C++ в треди,
в Русті в FSM, як і в JS

токіо транслюється в треди, чи в FSM?

tokio это async framework под Rust. Сам Rust реализует механизм для конвертации последовательного процедурного года в FSM, но не предоставляет механизма для его выполнения. Механизмы выполнения предоставляются сторонними async executor, tokio это один из них. Под капотом tokio там используется смесь green threads и OS threads. Там сильно много функционала и конфигурации, чтоб ответить на вопрос да/нет.

std::asynct C++ в треди,

Зачем такой async?

я ж казав — без тролінгу
уделывает плюсы, ага... «погнали наши городских — наши спереди, городские сзади»

Твоя «ключова фіча багатопоточність» реалізована жирним куском коду під капотом, який написаний на C чи C++

А RTL в C/C++ реализуется жирным куском кода на ассемблере.

У меня другой вопрос — а как юзать C с каким-нибудь GC? Smartpointers — это всё не то, и тем более реализация C++, где на грабли наступаешь практически сразу. С мягкими и твёрдыми указателями, кольцевыми ссылками, const и не-const smartpointers, enable_shared_from_this и прочим бредом.

Если у вас возникают проблемы с управлением памяти в c++, то стоит почитать Джеффа Элджера. Но говорить о том, что язык с gc может заменить язык как с gc, так и без него, немного наивно :)

Я понимаю, что возможно какой-то Джефф Элджер очень умный, но всем это пофиг, для управления памятью в Go ничего читать не нужно. И это ключевой аспект, приводящий разработку к строгому соответствию принципу KISS. Если нужно избавиться от GC, то можно писать на чистом C, и тогда ещё в дополнение получите преимущество отсутствия шедуллера горутин.

Если нужно избавиться от GC, то можно писать на чистом C, и тогда ещё в дополнение получите преимущество отсутствия шедуллера горутин.

Своим комментарием вы подтверждаете узкую специализацию go, в отличии от c++. Что же это за язык, для работы с которым надо знать другой язык?

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

Я понимаю, что возможно какой-то Джефф Элджер очень умный, но всем это пофиг

Вы сюда пришли умом мерятся или другими частями тела? Нет желания или времени разбираться в c++? Вас устраивает go? Нет вопросов, но не надо говорить, что go может заменить с++ или си.

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

Согласен, но как-то странно говорить о том, что палки и камни могут заменить пулемет.

палки и камни

Це ти руст і го?

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

Своим комментарием вы подтверждаете узкую специализацию go, в отличии от c++

На сегодняшний день узкая специализация уже у C++. Широкая у него была лет 20-30 назад. А сейчас обширный спектр задач, который ранее писался на C++ пишется под другие языки и сопутствующие технологии. Свои позиции C++ утратил во время популяризации java, и .Net вслед за этим, когда MS проиграла суд Sun по патентным правам на джаву. И на сегодняшний день энетерпрайз-разработка на C++ под Windows API свёрнута полностью. Ещё частично код на C++ можно было писать под WinRT, но с фейлом WinPhone это направление тоже умерло. На сегодняшний день есть задачи, что старый функционал, написанный на C++ Windows-приложений нужно портировать в облако, в сервисах на Go. Ну а задачи наподобие описанных в статье выше, каким способом лучше вычислять sin или логические операции, меркнут на фоне изменений в архитектурных решениях в целом.

Расскажите про «широкую» специализацию го. Например, на с++ прекрасно пишется межплатформенный толстый клиент под линукс, виндовз, мак ос, пишутся БД (включая no-sql), пишутся MQ брокеры, бигдата системы, геймдев (не мне вам об этом говорить), системы реального времени (от медицинских до космоса), включая встроенные систем. Даже некоторые вещи под мобилки пишется (это исключение, чем правило), операционные системы (как минимум под виндой). Что же пишется на го кроме докера, апишечек и простенкого батчпроцессинга? Серьезно интересно, что уже на не молодом языке было реализовано или еще только пишется сейчас серьезного с долгой поддержкой, а не очередной микросервис, который по сложности хоть на бейсике пиши.

З.Ы. если что мне с++ не заходит, просто реально хочется понять, как го может заменить с++ или другой распространенный язык без gc

операционные системы

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

При чем тут rust к go? Мы же обсуждаем как go может заменить c++.

межплатформенный толстый клиент под линукс

Чего-чего? Тут требуется разъяснительная бригада.

виндовз, мак ос

Откуда вы знаете, на чём и как они сейчас пишут? MS уже давно заявляла, что .Net у них флагманская платформа, под которую они будут писать всё, включая компоненты ОС.

пишутся БД (включая no-sql), пишутся MQ брокеры

Тут без разницы, на чём их писать. OrientDB например вообще переписан с C++ на java. Что-то ещё под ноду написано, поскольку там всё равно js.

бигдата системы, геймдев (не мне вам об этом говорить), системы реального времени (от медицинских до космоса)

Вот как раз и пишутся на Go, это целевой сегмент разработки на Go. Причём зачастую код переписывается с C++ где нет GC, на Go где есть GC. А всё почему? Потому, что архитектурные решения имеют первичное значение, а код C/C++ занимает сегодня нишу оптимизационных решений.

Чего-чего? Тут требуется разъяснительная бригада.

Есть огромное количество успешных проектов на QT. Например, приложения, написанные на QT, более кроссплатформенные, чем написанные на .net (включая mono).

Откуда вы знаете, на чём и как они сейчас пишут? MS уже давно заявляла, что .Net у них флагманская платформа, под которую они будут писать всё, включая компоненты ОС.

Сам майкрософт писал об этом. Он подумывал о переходе на rust. Замете, не на go. Надеюсь, вы понимаете, что ОС — это не только десктоп оболочка. Если так говорить, то линукс то же написан на с++ (смотрим, что там в KDE).

Тут без разницы, на чём их писать. OrientDB например вообще переписан с C++ на java. Что-то ещё под ноду написано, поскольку там всё равно js.

Вот вы сами говорите, что куча языков используется для написания БД. Хотя бы одно популярное БД есть на go? Или, хотя бы, не популярное.

Вот как раз и пишутся на Go, это целевой сегмент разработки на Go. Причём зачастую код переписывается с C++ где нет GC, на Go где есть GC. А всё почему? Потому, что архитектурные решения имеют первичное значение, а код C/C++ занимает сегодня нишу оптимизационных решений.

Приведите, хотя бы одну подобную систему, которая хотя бы на 30% была написана на go. Это не тролинг, мне реально интересно, как же оно все работает с gc от go.

P.S. могу ошибаться, но, насколько я знаю, OrientDB изначально был написан на java.

Есть огромное количество успешных проектов на QT.

И что это старое говно мамонта делает, запускается на десктопе под убунту, после установки всех примочек? Или для чего оно ещё надо?

приложения, написанные на QT, более кроссплатформенные, чем написанные на .net

А вот Google выпустил flutter, который компилируется под web, под android и ios, ещё собираются сделать фуксию, где приложения будут писаться на том же флаттере, у них походу видиние кроссплатформенности в несколько ином аспекте. Причём кто бы что не делал, там C++ чего-то не фигурирует в качестве ключевого языка разработки.

Сам майкрософт писал об этом. Он подумывал о переходе на rust. Замете, не на go.

То есть, MS терзается в сомнениях, на что бы ему перейти, то ли под .net теперь всё пилить, то ли на rust переходить.

Надеюсь, вы понимаете, что ОС — это не только десктоп оболочка.

Вот вы положили болт на разработку на C++ 10 лет назад, а создаётся такое впечатление, будто бы совсем только что.

Вот вы сами говорите, что куча языков используется для написания БД. Хотя бы одно популярное БД есть на go? Или, хотя бы, не популярное.

Стоп-стоп-стоп. Раз OrientDB переписали с C++ на java, значит что же это такое выходит, что java лучше чем Go подходит для написания БД? Ну раз на Go не переписали? Или может C++ там даже изначально никак не фигурировал?

Хотя бы одно популярное БД есть на go? Или, хотя бы, не популярное.

victoriametrics.com

Что же пишется на го кроме докера

перепиши кубернетес на цэпепе, victoria metrics, helm, vault, etcd, linkerd, prometheus та и еще куча софта в CNCF

Если у вас возникают проблемы с управлением памяти в c++, то стоит почитать Джеффа Элджера

А еще лучше Джона Гьенгсета

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

повір що так, проливає світло з іншого боку на той же с++

И что, в книге есть конкретные решения, которые можно применять в с++? Например, как в этой — www.amazon.com/...​-Jeff-Alger/dp/0120499428 ? Мы же сейчас не обсуждаем, чем лучше или хуже с++ и rust.

Сори, я не буду покупать за 5 долларов книгу с тремя отзывами. Если не затруднит, можете перечислить несколько «конкретных решений», которые можно применять в С++?

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

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

Можете привести пример «концепта» или «пространства памяти»? Спрашивюа не ради троллинга.

Поэтому мне не понятно, почему у вас такой повышенный интерес к управлении памятью в с++?

Потому что с моей точки зрения управление памятью в C++ мягко говоря хромает по сравнению с тем, что есть в более современных языках программирования (либо с полными управляемыми сборщиками мусора типа C# либо с серьезной статической верификацией типа как в Rust). Если в C++ возможны какие-то более грамотные подходы к управлению памятью чем «ложи все на кучу в смарт поинтеры» и «нанимай программистов, которые хорошо знают все подводные камни C++», очень хотелось бы про них узнать.

Потому что с моей точки зрения управление памятью в C++ мягко говоря хромает

Я понимаю вас. Но мне не понятно, как прочтение книги от Джона Гьенгсета поможет schwarzlichtbezirk разобраться в управлении памятью в с++? В книге от Джеффа Элджера предложены различные концепты, от счетчика ссылок, до gc. Обсуждать rust я не хочу, т.к. у меня нет такой экспертизы в rust, что бы провести глубокое сравнение c++ и rust. Если бы эта ветка обсуждения была бы о rust vs c++, я бы еще понял. Но мы здесь обсуждаем, как go может полностью заменить c++. А может go может заменить rust? И не имеет значение, что rust появился позже go :). У вас есть какие-либо аргументы за go в этих вопросах?

как прочтение книги от Джона Гьенгсета поможет schwarzlichtbezirk разобраться в управлении памятью в с++?

Я ничего не писал о том, что испытываю трудности с разбирательством в управлении памяти в C++, вы похоже видите то, что вам удобнее видеть.

Я понимаю вас. Но мне не понятно, как прочтение книги от Джона Гьенгсета поможет schwarzlichtbezirk разобраться в управлении памятью в с++?

У Гьенгсета описан принцип работы borrow checker и как «различные концепты», в которое, внезапно, входит и счетчик ссылок и смарт поинтеры и GC (про который, он, правда, не говорит), могут быть безопасно реализованы на основе этих механизмов.

Понимание принципов borrow checker позволяет видеть в C++ коде места, где есть возможность накосячить, и избегать их.

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

Также, когда приходит понимание, сколько механизмов требовалось запилить в Rust, чтоб дать разработчикам безопасную модель памяти, понимаешь наколько близко любая программа на C++ находится к undefined behavior, и вместо хиканек про «C++ неосиляторов», начинается параноидальный анализ своего и чужого кода на предмет лажи.

В книге от Джеффа Элджера предложены различные концепты, от счетчика ссылок, до gc.

Т.е. все, что может предложить язык, стремится в embedded и realtime — это аллоцировать все на куче, а еще лучше юзать GC, это немного убогая ситуация.

Но мы здесь обсуждаем, как go может полностью заменить c++.

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

не так, а так:
«перечислить несколько „конкретных решений“, которые можно применять в Rust»

з.і.
dou.ua/...​rums/topic/38670/#2432930

Я уже более 10 лет не пишу на с++ и не собираюсь возвращаться.
«перечислить несколько „конкретных решений“, которые можно применять в Rust»

Я немного устал писать о том, что сейчас идет обсуждение — как go может заменить с++. В можете посоветовать хотя бы одну книгу по управлению памятью в go, из которой будет понятно, как он может полностью заменить c++?

з.і.
dou.ua/...​rums/topic/38670/#2432930

Я думал, что из контекста понятно, что мы обсуждаем с++, а не все языки мира.

навіщо його заміняти?
є ж тонни легасі гівн мамонта.. його заміняти не буде, поки не розкладеться.

просто нове мало хто пише на С++
а для заміни С++ є С і Rust

В этой ветке идет обсуждение, что c++ можно без проблем заменить языком go. Тогда возникает вопрос, зачем вы пишите о rust или си, если есть go? Или это такие странные аргументы за go, что он может без проблем заменить c++ при помощи rust :)?

В этой ветке идет обсуждение, что c++ можно без проблем заменить языком go.

точно?
це в якомусь Законі написано?

Книга Джефа Элджера написана в 98 году, безнадежно устарела на сегодня. Не помню всего материала в ней, но запомнилось, что очень много в ней посвящено всяким умным, мудрым и гениальным указателям. В С++11 уже есть умные указатели, смысла тратить время на эту книгу сегодня не много.

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

Если под многозначительным словосочетанием «концепты управления памятью» подразумевается использование умных указателей, то полезнее почитать Скотта Мейерса, там намного практичнее описано и уже про 11 и 14 стандарты.

Там не только умные указатели. Например, введение транзакционную память, введение в GC (после прочтения понимаешь, почему GC не был введен и никогда не будет введен в стандарт) и многое другое. По мне, так глубина книги где-то рядом с книгами от Александреску. Понятно, что ее не стоит советовать джуну. Хотя, возможно, есть что-то более современное с таким же глубоким рассмотрением поднятых вопросов в книге. Не знаю. Я уже более 10 лет не пишу на с++ и не собираюсь возвращаться.

Я уже более 10 лет не пишу на с++ и не собираюсь возвращаться.

тим більше дивно, якщо така крута супер-пупер мова

Где вы видели, что бы я писал, что c++ — крутой супер-пупер язык? В этой ветке идет сравнение «спуер-пупер» языка go, который без проблем может заменить c++. Я пытаюсь понять, как он может заменить с++? Может быть вы видите, как go может заменить c++, например, в ядре винды или в проектах реального времени или ...?

наскільки я пригадую, ішлося про Rust
C++ не заміняють, а витісняють, і не одне тільки Го

Вообще то я пытаюсь понять

и как юзать вот этот go без gc?

Ссылочка на мой вопрос. А вот это ссылка на корневой комментарий.

Скиньте ссылку, где я могу получить ответ на

и как юзать вот этот go без gc?

Ну а если нельзя Go юзать без GC и GC в Go оптимизирован только под пропускную способность, то выходит, что на Go имеет смысл реализовывать задачи с большой пропускной способностью (и плевать на процессор и память). При этом реализация GC в Go не уплотняет память, что может привести к ее нехватки. Отсюда вывод — Go относительно узкоспециализированный язык/платформа. Да, есть много задач под его специализацию (например, апишечек на порядки больше, чем софта под мед. оборудование). Но ни как нельзя утверждать, что Go может заменить распространенный (пусть и легаси) язык/платформу с очень широким назначением. Rust? Может быть. Я не знаю. Но Go точно не вариант.

При этом реализация GC в Go не уплотняет память, что может привести к ее нехватки. Отсюда вывод — Go относительно узкоспециализированный язык/платформа.

Прошу прощения, а реализация под C++ уплотняет память?

Єдина мова, що хоч якось може потіснити плюси, це Раст, і то з натяжкою. І то, це треба дуже повірити у Раст, і те, що він не загнеться.

Решаем с сыном задачки на литкоде, он на c# / python, я на с++. Он все время удивляется, как так, решения на с++ часто в разы быстрее. Но тем неменее, я его отговариваю от с++, ну не надо он ему... слишком сложный язык, и стандарт 20 года вообще не делает его проще (в отличии от c++11, c++17) к сожалению.

в народі це називається накинути гів...на на вентилятор)

Автор не дивиться в корінь проблеми від слова «зовсім».
C++ досі часто використовується там де є ліба на C/C++ і треба її сапортити/інтегрувати/обв’язку робити.
А ліба саме на C++ тому що треба сапортити Win/Android/iOS/*nix/web і ще-там-щось. А компілятор C++ є практично під будь-що включаючи модерний веб, пульт до телика і кавоварку, на відміну від практично всіх «масових вбивць C++». Плюс купа кейсів коли є С/C++ SDK і немає більш нічого — звісно, можна реалізувати «свій варіант» але це час і гроші, і потім треба сапортити.
Відтак, C/C++ здохне тоді коли він перестане бути мовою по-замовчуванням для крос-платформи і для системної розробки (бо потім ті системні розробники пишуть SDK на тій же мові на якій решта системи написана)

перепрошую, але до чого С++ до С?
чому пишуть «С/С++» і «С++ не помре», коли потрібно писати, що «С не помре»?
С і С++, це як Java та JavaScript

А компілятор C++ є практично під будь-що

під С, а не під С++,
крім компілятора потрібно ще для С++ хоча б STL, чи ми про що, про С++ в стилі С?

Навіть на 8-бітне ардуїно штатний компілятор це вже C++ а не C

«сишные» компиляторы под процы идут всегда. «плюсовые» далеко не всегда (скорее, редко когда).

П.С. Ардуино — не проц.

Так а де я писав що це процесор?)

«Штатные компиляторы» — идут под процы, а не под платы.
И от производителей процов.

Мені здається комусь теж варто перевірити свої знання: «плата», «мікроконтроллер», «мікропроцесор», «ядро», «мікроархітектура», «ABI».
І під що з цього списку таки йде компілятор :)

І під що з цього списку таки йде компілятор

Как правило, лишь под проц.

Тобто, коли я під мікроКОНТРОЛЛЕР XC164CS-32F з ядром C166SV2 збирав код компілятором С++ під мікроАРХІТЕКТУРУ Siemens C166 — я робив щось не так? :)
Ех, зразу видно що я не профік по ембеду.

Тобто, коли я під мікроКОНТРОЛЛЕР XC164CS-32F з ядром C166SV2 збирав код компілятором С++ під мікроАРХІТЕКТУРУ Siemens C166

„XC164CS-32F/32R 16-Bit Single-Chip Microcontroller with C166SV2 Core”
www.infineon.com/...​3136c9a8b01136d9c9f930069

„Supported by a Large Range of Development Tools like C-Compilers, MacroAssembler Packages, Emulators, Evaluation Boards, HLL-Debuggers, Simulators, Logic Analyzer Disassemblers, Programming Boards”

Может, это был таки „сишный” компилятор? Просто, кто-то не понимает разницы между „си” и „плюсами”...

А що, в сішці 2022 вже є конструктори, деструктори, ключові слова new/delete, віртуальні методи і exceptions?
Якщо є — то я вибачаюсь, справді щось не те подумав.

new/delete, віртуальні методи і exceptions?

Ты с этим всем «эмбед-софт» писал? Хм...

Без exceptions, а в решті я нічого поганого не бачу.
Особливо потішно коли ті ж люди хто фиркають на плюсові віртуальні методи починають ліпити власну реалізацію того ж самого на голій сішці (в вигляді сирих вказівників на методи які перекидаються туди-сюди, або вказівників на таблиці методів... oh wait...) і потім з піною з рота доводять що це в 100500 тисяч разів краще ніж таблиця методів в плюсах.

Зрештою я ніде і не кажу що я embedded developer, в мене таких слів і в резюме нема. Відтак, навіть exceptions цілком можна було б використовувати і не соромитись.

в вигляді сирих вказівників на методи які перекидаються туди-сюди, або вказівників на таблиці методів

Таблицы методов и указатели на функции — это всё вещи в эмбеде вполне легитимные. До тех пор, пока всё остаётся статическим.

Но new/delete? Наследование/полиморфизм?? Бгг...

П.С. Впрочем, скоро хипстеры в эмбедах начнут кубернетcы с прочими эластиками крутить.

Так а в чому різниця між malloc + ручна ініціалізація проти new (в старообрядній формі яка не кидає ексепшн а вертає NULL)?

Далі, про «статичність»: з того що я бачив в реальних проектах (писав не я, якщо що) це системи «модулів» які під час ініціалізації збирають call chain на вказівниках в linked list.
По факту, будь там плюси і абстрактні класи з точки зору коду який виконується воно нічим би не відрізнялось.

По факту, будь там плюси і абстрактні класи з точки зору коду який виконується воно нічим би не відрізнялось.

Будь там «плюсы» — к багам от кривых рук разработчиков софта, прибавились бы ещё баги от кривых рук разработчиков «плюсового» компилятора.

Окей, нарешті ми докопуємось до суті — компілятори і справді сумні, по правді навіть деякі сішні конструкції компілювались в такий асемблерний код що диво брало.
Взагалі є надія що по мірі здешевлення ядер на мейнстрімних µArch (кхе-кхе... ARM... кхе...) проблема вирішиться шляхом переходу на мейнстрімні ж компілятори. Ну і більш сучасні ядра на кшталт Xtensa теж йдуть з доволі свіжими GCC/Clang що радує.

. Пробую щось нове, але щоразу повертаюсь до С++,

є просте рішення: «не брати тяжкого в руки, а дурного в голову», тобто на всі непристойні пропозиції щодо С++ відповідати: «сам не курю і вам не совєтую», і ти ба, буде наче сім бабок пошептало, ніякого С++ в межах обозримого горизонту

Numba: певно Ви мало з нею, мало працювали, бо Numba компілює не Python, а лише певну його підмножину (схожу на C + numpy). Тобто для неї потрібно спеціально переписувати пітонячий код на свою «під-мову», що досить нетривіально, бо помилка (з точки зору Numba, не Python) у коді може вилетіти й через годину обчислень. Відлагодження немає, що за помилки не зрозуміло, інколи потрібно днями вивчати транслятор Numba, щоб зрозуміти, яка ідіоматична пітоняча конструкція її завалила. Ще буває, що з код з @jit та без, видає різний результат — happy debugging☹. Нажаль, більш схоже, не на вбивцю, а доходягу

C++ вмирає з початку 2000-х, а компанії у 2022 хайрять як скажені на проекти на С++, ще й з нуля розробляють їх.

Я працював з 8 мовами програмування та більш ніж з 200 бібліотеками та фреймворками. Так можна щотижня випускати за статтею, додаючи у шаблоні «Справжні вбивці...» нову назву

Spiral, Numba, ForwardCom

Все, вирішено — в понеділок на мітингу пропоную замовнику переписати наші скікісь там мільйонів рядків С++ коду на Spiral. Якщо не погодиться — в вівторок і середу запропоную Numba та ForwardCom :)

Якщо серйозно, то автор, звичайно, правий — С++ помирає, але це відбувається приблизно з тією ж швидкістю, як Земля падає на Сонце. Ну, тобто, через скількісь там мільйонів-мільярдів років це станеться, але на наш вік ще вистачить :)

Ідея застосування пітончику, сішки, вебасма і іншого там, де це потрібно, звичайно, правильна. Але це все, як правило, плюсовому проєкту допомагає в плані піару і маркетингу, а не змінює його на ці мови.

Тулзи цікаві, дякую. Але з посилом і висновками складно погодитись, якось тепле з м’яким у купу намішано.

Жахлива кодова база з купою легасі, провальні архітектурні рішення, відсутність гайдлайнів, недосвідчені розробники і текучка кадрів, відсутність ідеї maintainability коду чи навіть банального код-рев’ю, кастомер, що не бажає витрачатись на рефакторінг? То, звісно, C++ в усьому винен! А написання проєкту будь-якою іншою мовою в таких умовах, звісно, призвело б до протилежного результату і все було б зашибісь.

C++ неоптимально використовувати для якоїсь конкретної задачі? Всьо, воно вже майже мертве! Десь так з 1985 року. А ніяких інших задач, доменів і стрімкого розвинення мови просто не існує.

Вибір мови залежить не тільки від синтаксису, але й інфраструктури (як-от банальної наявності бібліотек чи компіляторів під конкретну залізяку/ОС), доступності (і рейту) розробників, домену, регуляцій в цьому домені. Ніхто вам не дозволить запхати jit-компіляцію в критичну ділянку коду, наприклад. Чи писати скіль-небудь складну кодову базу на асемблері чи брейнфаку, який в усьому світі знають півтора інваліда, якомусь нещасному ж це потім підтримувати. Чи розводити зоопарк технологій там, де краще обійтись однією універсальною. У плюсів є свої ніші і роботи там вистачить на два життя вперед.

Щоб щось померло, потрібно щоб щось народилось. Достойного поки не бачу. Зрушились на 20% вперед, а тішимось ніби в 5 раз краще стало. Що краще? Масиви, об’єкти тепер легко записати в один рядок? А що сталось із швидкодією. В Пайтоні вона в 10 раз знизилась при тому, що ПК в декілька разів швидше працюють. Обсирали Бейсік, а на зміну прийшов Пайтон з схожим синтаксизом. Ще попередню мову досконало не знаєш, а вже цікаво а що там в новій мові? Абсолютно нічого. На 5% цікавіші рішення, але прийдеться вивчати всі нюанси окрім мови. А якщо ще й мова бідна як JS, то прийдеться ще й фреймворки вивчати.

Достойного поки не бачу.

+1 за Rust. Приємно працювати з ним, особливо як для low-level мови.

Опоную черговiй от такiй роботi тролингу, яку я вже читаю з 2002 як я пересiв з Turbo Pascal на Borland C++ 3.1 та потiм 5.0, дебiлдер i далi. За цей час в таких статтях С++ все помирає, то його С# нищiть, то Scala то, ще що небудть

Spiral

тут взагалi питання не до мови программуваня загалом, а до компiлятора clang i до його оптимiзацiй. Далi типовий синтетичний бенчмарк з замiром абстрактного Чебурашки в галактицi Андромеди, тобто з метою демонстрацi окремого випадку. Так само як з complile time regex було (додано до стандарту С++ 23 ).

Numba

Напищiть драйвер будь якого пристрою, опрерацiйну ситсему на Pyhon i поговоримо. Порiвнювати Python i C не корректно взагалi, це мови рiзного рiвня обстракцiй. Загального призначення i скрiптова прикладного призначення. Тобто Python потрiбен для пришвидшення программування прикладних програм, того, що нема сенсу оптiмiзувати — а треба створити швидко для рiшеня задачi накшталд тренування нейроної ciтки (а сам код мат моделi нейронки написано на С++), чи пакування RPM пакету (сам код LZMA2 пакування написано теж на С++). Так само не корректно порiвнювати С i Assembler

@cuda.jit

не вразило, от вам

      #pragma omp parallel for

Або Boost.Compute, CLBlast, Torch, Caffe, OpenCV тощо. OpenCL i CUDA C — з початку рiдний С API, тобто нульовий еффорд щоб почати щось робити.

ForwardCom

Зробiть на TASM, який ви витягнули з могильнику Borland, принаймi аналог vector з STL, щоб використовував шаблони. Можете навiть спробувати якийсь сучасний FASM, NASM або старий добрий GAS. Ще раз порiвнювати мови рiзного рiвня абстракцiї принципово не корректно.

Я складаю рівняння в SymPy,

Тобто для конкретно вашої роботи треба прикладний рiвень абстракцiй де Python пiдiйде краще, чому через це С++ помре ?

В програмуванні немає «абстракції» це слово украв із математики алгебраїст Стєпанов. Є автоматизація. Якщо не можете написати вектор на асемблері самостійно, покличте компілятор, він напише його за вас. Це не абстракція, це класична автоматизація. Машина робить роботу за людину.

Абстракція є в математиці. В алгебрі. Тому парадоксально, а насправді ні, що SymPy (або будь яка система комп’ютерної алгебри) справляється з роботою плюсів — перетворення абстрактних рівнянь на конкретний код — краще за плюси. Через це С++ вже помер. Питання лише, якою мірою.

За правилом древнiх перед вступом в дискус, треба з’ясування понять. Вiзьмем пояснення поняття вiд Боецiя i Арестотелья:

Абстра́кція (лат. abstractio — «відвернення, виведення»; введено Боецієм як переклад грецького терміна, використаного Аристотелем) — одна з найважливіших дій мислення,[1] теоретичне узагальнення, а також метод наукового дослідження, який полягає у тому, що суб’єкт виокремлює реальні необхідні загальні універсальні властивості чи ознаки об’єкту котрий вивчається, усувається від інших несуттєвих прикмет об’єкту отже не враховує його (об’єкта) неістотні сторони й особливості.

uk.wikipedia.org/wiki/Абстракція
Цей фiлософский термiн в дисциплiнi програмування визначено так:

В програмуванні, абстрагува́ння — спосіб та метод відокремлення деталей з метою отримання можливості зосередитись на найважливіших особливостях об’єкта.

uk.wikipedia.org/...​рагування_(програмування
Тобто assembler це найнижчий з можливих рiвнiв абстрагування, орiнтований на команди обладнання CPU,GPU, АЛУ тощо. Процедурнi ЯВУ типа FORTRAN,С,Pascal,Modula 2 вводять наступний рiвень — опреаторiв та пiдпрограм, потрiбного для складного ситсемного программування, створення операцiйних систем, драйверiв, керуючих програм. Cкриптовi та bytecode iнтерпритатори мови типу — Java та Python на рiвнi абстракцiй прикладних задачь, наукових та iнженерних обчислень, автоматизацiй бiзнес процессiв. С++ по середенi мiж системним i прикладним рiвнями абстракцiй, саме тому i популярний серед розробникiв десяткi рокiв. Створено мiжнародний стандарт, безлiч компiляторiв тощо.

Але є одне «але». Більшість коду сумарно за увесь життєвий цикл витрачає на виконання менше часу, аніж витрачається на його написання, читання, і звичайно ж на намагання змусити його працювати як задумано.

Тому я на Java. І лише інколи читаю cpp, ще рідше пишу.

Так, машинний час — це гроші. Але створення та підтримка коду — це також гроші та час. І тому ці цифри варто порівнювати, щоб зайвий раз в погоні за оптимізацією не втрачати гроші та час. Бо купити машинний ресурс зазвичай дешевше, його легше масштабувати. А от ціну помилки, ціну затримки, ціну ризику — не масштабуєш, це вузьке місце.

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

В високо нагружених сервiсах, компьютерних iграх, тренажерах, embedded i багато де ще — нi не дешевше. Iнодi дуже сильно не дешевше.

Незрозуміло як в список потрапили тренажери — це дорого і там найдорожче залізо яке лише існує на ринку поставити не проблема.

Дефект перекладу, маються на увазі Simulators. Наприклад Flight Training Simulation.

Якщо мова про домашніх юзерів які собі літають в новому MSFS — то це звичайна комп’ютерна забавка.
Якщо про професійні Flight Simulation Training Device — то навіть в розгар криптобуму парочка (або й пару десятків) додаткових RTX3090 ніяк не вплинули б на кінцеву ціну.

Скажімо тренажер 2010 року випуску, софт треба обновити, додати фітчь, пофіксити баги, покращіти перформанс, переналашиувпти на літак нової серії. А абгрейд заліза, це нова сертифікація, що коштуватиме мільйони прямих витрат і багато часу доки тренажер простоює і нічого не приносить, з приміщеннями, електрикою, обслуговуючим персоналом з немаленькими зарплатами тощо.

«Переналаштувати на літак нової серії» це і так нова сертифікація. Чи, вірніше, кваліфікація)

Як я чув з софтом усе ніби швидше набагато. Існує документ як робиться така сертифікація www.easa.europa.eu/...​ion-training-devices-fstd і обслуговування.

Дуже сильно впирається в конкретне national authority навіть в рамках Євросоюзу де правила, наче б то, єдині і виставляє їх EASA.
А все тому в кваліфікаційних тестах багато суб’єктивщини — як з інспектором домовишся так і буде, відповідно, конкретна процедура апдейту софту або заліза впирається в те, про яку країну мова.

Embedded це широке поняття, це може бути і 4-бітний проц з мікрохвильовки і лінукс, що крутиться на 2+ ядрах, кожне на 2ГГц з 2 Гб пам’яті.
В першому випадку простіше на С, ассемблері писати, в другому навіть на пітоні. Для С++ тут майже немає місця. Тим більше в критичних ситуаціях я можу викликати С код з пітону або джави.

Embedded це широке поняття

Завдяки HR-ам. Embedded залишився лише там де пишуть дрова, або зовсім лоу-левел програмування якесь з хардваром, навіть soft-realtime ECU у автомобіль це вже не ембеддед, а звичайне прикладне програмування, з деякими «але».

Для С++ тут майже немає місця.

:D

нє, ну є звичайно окремі потуги в інтернеті писати на С++ під стм32, але в цьому немає особливого сенсу

Ну якщо мова йде о стм32, то так, повністю згоден, це оверкілл буде хрестики приліплювати.

та ладно ulibc++ в допомогу і хрести на стм

та ладно, он шукють в сусідні темі читача УАРТ на удаві з малини, труь ембедедед

Серединку пропустили навмисно? Ті ж роутери, на яких для джави чи пітону не вистачить флеша й оперативи, а лінух нормально собі бігає. І торенти усякі запускаються. І оті торенти, та купа роутерної логіки — на С++. Це як приклад ембедеда.

Зауваження справедливе. «Час програмістів дорожчий за час виконання» — це класична мантра з дев’яностих, на якій виросло вже не одно покоління менеджерів. Але як тільки час виконання перейшов із категорії прихованих витрат та ще і чужих (як це було із коробковим софтом в тих самих дев’яностих) у категорію явних витрат і своїх, виявилось, що мантра працює... м’яко кажучи не завжди.

Ніщо так не міняє світогляд, як рахунок за AWS.

Я не сказав що така ситуація усюди. Але левова доля софту — саме така. Важливіше щоб він працював, і працював передбачувано. Швидкість — не головний фактор для >99.99% програм.

Але є величезний ринок саме для швидкого софту. І С++ звідти не піде мабуть ще років 50 щонайменше. Бо є такий софт, яким користуються багато. Є такий, який працює безперервно, і має працювати автономно. Є безліч заліза, яке працює від батарей та батарейок.

Основна проблема ринку швидкого софту — відсутність легких у використанні метрик, які були б доступні кінцевим користувачам. Коли це з′явиться, може статися тиха революція, і такий хлам як Вайбер чи Вотцап — підуть на звалище історії попри популярність.

е для швидкого софту. І С++

а є ще «бистра Настя»

Коли це з′явиться, може статися тиха революція, і такий хлам як Вайбер чи Вотцап — підуть на звалище історії попри популярність

А до чого тут ці флуділки?

Автор нагадує школяра — «я ж програміст». Окрім власних вигаданих слів не сказав нічого, що мало б сенс.

Дочитав до слів «поліноміальна модель»

медаль Назару, я навіть 1ше речення ніасіліл, зразу в камєнти ушол

C++ вмирає тільки в головах таких розробників як автор...

Мені шкода що мої факти ображають ваші переконання.

Ваші факти засновані на припущеннях, що для C++ інших застосувань крім super-high-performance-in-realtime не існує. І що все робиться в клауді, де це супер-важливо, а якщо це не важливо, то і C++ не потрібен. Ви поширюєте свій нішевий досвід на всю галузь, і це типова помилка сприйняття. А між іншим, є ще desktop та embedded, де в першому випадку бажана крос-платформеність із коробки (привіт, Qt), а в другому — ощадливе застосування ресурсів при високих вимогах до UI (знов, привіт Qt). Тому ні, допоки хромбукі не витіснили звичайні PC, а цивілізація не повернулась до вогнищ та печер, C++ точно не помре.

с++ буде вмирати довго тому, що навгонокоджено говнокода мегабільонтон і його тре підчищати, підтримувати і, вашумать розширювати функціонал
он в США кажуть кобольщиків із анабіозу витягують

Сила Раста не в мікрооптимізаціях і суперефективному суперрозумному компіляторі, а в тому, що він примушує програміста наводити порядок у голові, по можливості виражати інваріанти кодом, а не знаннями у одній-єдиній голові, та ставитись до памʼяті більш-менш уважно.

Про такі от обчислювальні ніші дійсно згодний, там Раст непрактичний, але ж як радує те, про що йдеться в статті, що навіть у тій ніші С++ відстає від заліза і поступово стає непотрібним.

Раст сам по собі дуже крутий. Якщо глянути на результати щорічного опитування С++ програмістів, а саме на частину «що вас фруструє» (isocpp.org/...​cpp-developer-survey-lite), то не важко помітити, що Раст лікує більшість зазначених там проблем.

Але це все ще робота над помилками. Це, в термінах Форда, faster whorses. Це хороший і правильний крок від минулого, але ще не крок у майбутнє.

whorses

Ааа это задумывался такой гибрид или как??

насправді, Rust нічого не лікує....через пару років буде ще одна «кохана мова», ще більш коханіша чим коханий Rust ... але ОПП/ООД головного моску воно не вилікує

А потім приходить менеджер пам’яті і ввалює з ноги всім любителям витрачати час на мікрооптимізації через аллокацію строки посеред критичного коду.

Або не приходить. Або приходить коли ніхто не чекає.

З пам’яттю взагалі непросто. Наприклад, в Review Guidelines on Software Languages for Use in Nuclear Power Plant Safety Systems (www.nrc.gov/...​ontract/cr6463/index.html) перше правило роботи з динамічною пам’яттю — не використовувати динамічну пам’ять взагалі.

І отримуємо старенький сабсет embedded C++. Без STL але з ООП.

Підписатись на коментарі