Merhaba! Ben Oleksandr Kaleniuk ve bir C++holic'im. 17 yıldır C++ ile yazıyorum ve tüm bu 17 yıldır bu yıkıcı bağımlılıktan kurtulmaya çalışıyorum.
Her şey 2005 yılında bir 3 boyutlu uzay simülatörü motoruyla başladı. Motor, C++'ın 2005'te sahip olduğu her şeye sahipti. Üç yıldızlı işaretçiler, sekiz bağımlılık katmanı ve her yerde C tarzı makrolar. Montaj parçaları da vardı. Yineleyiciler Stepanov tarzı ve meta kod Alexandrescu tarzı. Kodda her şey vardı. Tabii ki en önemli sorunun cevabı hariç: neden?
Bir süre sonra bu soruya bile yanıt verildi. Sadece “ne için” değil, “nasıl oldu” diye. Motorun yaklaşık 8 yıldır 5 farklı ekip tarafından yazıldığı ortaya çıktı. Ve her ekip, eski kodu yeni tasarlanmış ambalajlara sararak projeye en sevdikleri modayı getirdi ve bunu yaparken yalnızca 10-20 mikrokarmalık işlevsellik ekledi.
İlk başta, dürüstçe her küçük şeyi ellemeye çalışıyordum. Bu hiç de tatmin edici bir deneyim değildi ve bir noktada pes ettim. Hâlâ görevleri kapatıyor ve hataları düzeltiyordum. Çok üretken olduğumu söyleyemem ama kovulmayacak kadar da iyiydim. Ama sonra patronum bana şunu sordu: "Gölgelendirici kodlarından bazılarını Assembly'den GLSG'ye yeniden yazmak ister misin?" Bu GLSL'nin neye benzediğini Tanrı bilir diye düşündüm ama C++'dan daha kötü olamaz diye düşündüm ve evet dedim. Daha kötü değildi.
Ve bu bir tür kalıp haline geldi. Hâlâ çoğunlukla C++ ile yazıyordum ama ne zaman birisi bana "C++ dışında bir şey yapmak ister misin?" diye sorsa Emindim!" ve ne olursa olsun o şeyi yaptım. C89, MASM32, C#, PHP, Delphi, ActionScript, JavaScript, Erlang, Python, Haskell, D, Rust ve hatta aşırı derecede kötü InstallShield kodlama dilinde yazdım. VisualBasic'te, bash'ta ve yasal olarak hakkında konuşamadığım birkaç özel dilde yazdım. Hatta tesadüfen kendim de bir tane yaptım. Oyun tasarımcılarının kaynak yüklemeyi otomatikleştirmesine yardımcı olmak için basit bir lisp tarzı yorumlayıcı yaptım ve tatile çıktım. Geri döndüğümde tüm oyun sahnelerini bu tercümanda yazıyorlardı, bu yüzden en azından projenin sonuna kadar bunu desteklemek zorundaydık.
Yani son 17 yıldır gerçekten C++'ı bırakmaya çalışıyordum ama her defasında yeni ve parlak bir şey denedikten sonra geri dönüyordum. Yine de C++ ile yazmanın kötü bir alışkanlık olduğunu düşünüyorum. Güvensizdir, sanıldığı kadar etkili değildir ve bir programcının zihinsel kapasitesinin korkunç bir kısmını, yazılım yapmakla hiçbir ilgisi olmayan şeylere harcar. MSVC'de uint16_t(50000) + uin16_t(50000) == -1794967296
olduğunu biliyor musunuz? Neden biliyor musun? Evet, ben de öyle düşünmüştüm.
Gençleri tehlike konusunda uyarmanın vazgeçemeyen alkoliklerin ahlaki sorumluluğu olduğu gibi, genç nesli C++ mesleği haline getirmekten caydırmanın uzun süredir C++ programcılarının ahlaki sorumluluğu olduğuna inanıyorum.
Ama neden vazgeçemiyorum? Sorun ne? Sorun şu ki, hiçbir dil, özellikle de "C++ katilleri" olarak adlandırılan diller, modern dünyada C++'a göre gerçek bir avantaj sağlamamaktadır. Tüm bu yeni diller çoğunlukla programcıyı kendi iyiliği için dizginlemeye odaklanıyor. Bu sorun değil, ancak kötü programcılarla iyi kod yazmak, transistörlerin her 18 ayda iki kat arttığı ve programcıların çalışan sayısının her 5 yılda iki kat arttığı 20. yüzyılın bir sorunudur.
2023 yılında yaşıyoruz. Dünyada tarihte hiç olmadığı kadar deneyimli programcılarımız var. Ve artık verimli bir yazılıma her zamankinden daha fazla ihtiyacımız var.
XX yüzyılda işler daha basitti. Bir fikriniz var, onu bir kullanıcı arayüzüne sarıyorsunuz ve onu bir masaüstü ürünü olarak satıyorsunuz. Yavaş mı? Kimin umurunda! On sekiz ay içinde masaüstü bilgisayarlar zaten 2 kat daha hızlı olacak. Önemli olan pazara girmek, özellikleri satmaya başlamak ve tercihen hatasız olmaktır. Böyle bir ortamda, elbette, eğer bir derleyici programcıların hata yapmasını engelliyorsa – bu iyi! Çünkü hatalar para kazandırmaz ve özellik ya da hata eklerlerse programcılarınıza ödeme yapmanız gerekir.
Şimdi işler farklı. Bir fikriniz var, onu bir Docker konteynerine sarıyorsunuz ve bulutta çalıştırıyorsunuz. Artık gelirinizi, eğer onların sorunları ortadan kalkarsa, yazılımınızı çalıştıran insanlardan alırsınız. Tek bir şeyi doğru yapsa bile, paranızı alırsınız. Ürününüzün yeni bir versiyonunu satmak için uydurma özelliklerle doldurmanıza gerek yok. Öte yandan kodunuzun etkisizliğinin bedelini ödeyen kişi artık kendinizsiniz. Her yetersiz rutin AWS faturanızda gösterilir.
Dolayısıyla yeni ortamda artık daha az özelliğe, ancak sahip olduğunuz her şey için daha iyi performansa ihtiyacınız var.
Ve birdenbire tüm "C++ katillerinin", hatta tüm kalbimle sevdiğim ve saygı duyduğum Rust, Julia ve D gibilerin bile 21. yüzyılın sorunlarına çözüm getirmediği ortaya çıktı. Hala XX'de sıkışıp kalmışlar. Daha az hatayla daha fazla özellik yazmanıza yardımcı olurlar, ancak kiraladığınız donanımın son flopunu sıkıştırmanız gerektiğinde pek yardımcı olmazlar.
Bunlar size C++'a göre rekabet avantajı sağlamaz. Veya bu konuda, hatta birbirlerinin üzerinde. Hatta çoğu, örneğin Rust, Julia ve Cland aynı arka ucu paylaşıyor. Hepiniz aynı arabayı paylaşırsanız araba yarışını kazanamazsınız.
Peki, hangi teknolojiler size C++'a veya genel anlamda tüm geleneksel ileri teknoloji derleyicilere göre rekabet avantajı sağlıyor? İyi soru. Sorduğuna sevindim.
Ancak Spiral'in kendisine geçmeden önce sezgilerinizin ne kadar iyi çalıştığını kontrol edelim. Sizce hangisi daha hızlı: standart bir C++ sinüs fonksiyonu mu, yoksa sinüsün 4 parçalı polinom modeli mi?
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;
Sonraki soru. Kısa devre ile mantıksal işlemler kullanmak veya bir derleyiciyi bundan kaçınmak için kandırmak ve mantıksal ifadeyi toplu olarak hesaplamak daha hızlı ne işe yarar?
if (xs[i] == 1 && xs[i+1] == 1 && xs[i+2] == 1 && xs[i+3] == 1) // xs are bools stored as ints // 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)
Ve bir tane daha. Üçlüleri daha hızlı ne sıralar: takas sıralaması mı yoksa indeks sıralaması mı?
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;
Tüm soruları kararlı bir şekilde, hiç düşünmeden veya Google'da arama yapmadan yanıtladıysanız, sezgileriniz sizi yanıltmış demektir. Tuzağı görmedin. Bu soruların hiçbirinin bağlam olmadan kesin bir cevabı yoktur.
Kod hangi CPU veya GPU'yu hedefliyor? Kodu hangi derleyicinin oluşturması gerekiyor? Hangi derleyici optimizasyonları açık, hangileri kapalı? Ancak tüm bunları bildiğinizde veya daha iyisi her bir çözümün çalışma süresini ölçtüğünüzde tahmin etmeye başlayabilirsiniz.
Bir polinom modeli, -O2 -march=native ile clang 11 ile oluşturulmuşsa ve Intel Core i7-9700F üzerinde çalıştırılmışsa standart sinüsten 3 kat daha hızlıdır . Ancak --use-fast-math özellikli nvcc ve GeForce GTX 1050 Ti Mobile gibi GPU üzerinde oluşturulmuşsa, standart sinüs modelden 10 kat daha hızlıdır.
Vektörleştirilmiş aritmetik için kısa devre mantığıyla işlem yapmak i7'de de anlamlıdır. Snippet'in iki kat daha hızlı çalışmasını sağlar. Ancak aynı clang ve -O2'ye sahip ARMv7'de standart mantık, mikro optimizasyondan %25 daha hızlıdır .
İndeks sıralaması ile takas sıralaması arasında indeks sıralaması Intel'de 3 kat, takas sıralaması ise GeForce'da 3 kat daha hızlıdır .
Yani hepimizin çok sevdiği sevgili mikro optimizasyonlar kodumuzu hem 3 kat hızlandırabilir hem de %90 yavaşlatabilir. Her şey bağlama bağlıdır. Bir derleyici bizim için en iyi alternatifi seçebilseydi ne kadar harika olurdu; örneğin, derleme hedefini değiştirdiğimizde indeks sıralaması mucizevi bir şekilde takas sıralamasına dönüşebilirdi. Ama yapamadı.
Derleyicinin sinüsü bir polinom modeli olarak yeniden uygulamasına, hassasiyeti hız ile değiştirmesine izin versek bile, yine de hedef hassasiyetimizi bilmiyor. C++'da “bu fonksiyonun bu hatayı almasına izin verilir” diyemeyiz. Elimizdeki tek şey “--use-fast-math” gibi derleyici bayrakları ve yalnızca bir çeviri birimi kapsamında.
İkinci örnekte, derleyici değerlerimizin 0 veya 1 ile sınırlı olduğunu bilmiyor ve muhtemelen yapabileceğimiz optimizasyonu öneremiyor. Muhtemelen uygun bir bool tipi kullanarak bunu ima edebilirdik ama bu tamamen farklı bir problem olurdu.
Ve üçüncü örnekte, kod parçaları eşanlamlı olarak tanınamayacak kadar farklıdır. Kodu çok fazla detaylandırdık. Eğer sadece std::sort olsaydı, bu zaten derleyiciye algoritmayı seçme konusunda daha fazla özgürlük verirdi. Ancak hem büyük dizilerde verimsiz oldukları hem de std::sort genel yinelenebilir bir kapla çalıştığı için takas sıralamasını değil indeks sıralamasını seçmezdi.
Ve Spiral'e bu şekilde ulaşıyoruz. Carnegie Mellon Üniversitesi ve Eidgenössische Technische Hochschule Zürich'in ortak projesidir. TL&DR: sinyal işleme uzmanları, her yeni donanım için en sevdikleri algoritmaları elle yeniden yazmaktan sıkıldılar ve bu işi onlar için yapan bir program yazdılar. Program, bir algoritmanın üst düzey tanımını ve donanım mimarisinin ayrıntılı açıklamasını alır ve belirtilen donanım için en verimli algoritma uygulamasını yapana kadar kodu optimize eder.
Fortran ve benzerleri arasında önemli bir ayrım olan Spiral, gerçekten de bir optimizasyon problemini matematiksel anlamda çözüyor. Çalışma süresini bir hedef fonksiyon olarak tanımlar ve donanım mimarisi tarafından sınırlanan uygulama değişkenlerinin faktör uzayında global optimumunu arar. Bu, derleyicilerin gerçekte asla yapmadığı bir şeydir.
Bir derleyici gerçek optimumu aramaz. Programcılar tarafından öğretilen buluşsal yöntemlerin rehberliğinde kodu optimize eder. Esasen bir derleyici, en uygun çözümü arayan bir makine olarak çalışmaz, daha ziyade bir montaj programcısı olarak çalışır. İyi bir derleyici, iyi bir montaj programcısı gibi çalışır, ancak hepsi bu.
Spiral bir araştırma projesidir. Kapsamı ve bütçesi sınırlıdır. Ancak gösterdiği sonuçlar zaten etkileyici. Hızlı Fourier dönüşümünde, çözümleri hem MKL hem de FFTW uygulamalarından belirgin bir şekilde üstün performans gösteriyor. Kodları ~2 kat daha hızlıdır. Intel'de bile.
Başarının büyüklüğünü vurgulamak için MKL, Intel'in, yani donanımlarını en çok nasıl kullanacağını bilen kişilerin hazırladığı Math Kernel Library'dir. Ve WWTF AKA "Batı'daki En Hızlı Fourier Dönüşümü", algoritmayı en iyi bilen adamların hazırladığı son derece uzmanlaşmış bir kütüphanedir. Her ikisi de yaptıkları işte şampiyon ve Spiral'in ikisini de iki kat yenmesi şaşırtıcı.
Spiral'in kullandığı optimizasyon teknolojisi tamamlanıp ticarileştirildiğinde, yalnızca C++ değil, Rust, Julia ve hatta Fortran bile daha önce karşılaşmadıkları bir rekabetle karşı karşıya kalacak. Üst düzey algoritma tanımlama dilinde yazmak kodunuzu 2 kat daha hızlı hale getiriyorsa neden kimse C++ ile yazsın ki?
En iyi programlama dili zaten iyi bildiğiniz dildir. Onlarca yıldır çoğu programcı için en iyi bilinen dil C olmuştur. Aynı zamanda diğer C benzeri dillerin ilk 10'da yer almasıyla birlikte TIOBE endeksinin de başında yer almaktadır. Ancak yalnızca iki yıl önce duyulmamış bir şey oldu. C ilk sırayı başka bir şeye verdi.
“Başka bir şey” Python gibi görünüyordu. 90'larda kimsenin ciddiye almadığı bir dildi çünkü zaten bolca sahip olduğumuz başka bir betik diliydi.
Birisi şöyle diyecek: "Ah, Python yavaş" ve bu terminolojik bir saçmalık olduğu için aptal gibi görünecek. Tıpkı bir akordeon ya da tava gibi, bir dil de hızlı ya da yavaş olamaz. Tıpkı bir akordeonun hızının kimin çaldığına bağlı olması gibi, bir dilin "hızı" da derleyicisinin ne kadar hızlı olduğuna bağlıdır.
Birisi şöyle devam edebilir: "Fakat Python derlenmiş bir dil değildir" ve bir kez daha başarısız olabilir. Çok sayıda Python derleyicisi var ve bunlardan en umut verici olanı da bir Python betiği. Açıklamama izin ver.
Bir zamanlar bir projem vardı. Orijinal olarak Python'da yazılan ve daha sonra "performans için" C++ ile yeniden yazılan ve daha sonra GPU'ya taşınan bir 3D baskı simülasyonu; bunların hepsi ben gelmeden önce. Daha sonra, derlemeyi Linux'a taşımak için GPU kodunu optimize etmek için aylar harcadım. Tesla M60, o noktada AWS'deki en ucuzu olduğundan ve C++/CU kodundaki tüm değişikliklerin Python'daki orijinal kodla birlikte doğrulanması nedeniyle. Yani normalde uzmanlaştığım şeyler, yani geometrik algoritmalar tasarlamak dışında her şeyi yaptım.
Sonunda her şey çalışır hale geldiğinde, Bremen'den yarı zamanlı çalışan bir öğrenci beni aradı ve sordu: "Demek heterojen konularda iyisin, GPU'da bir algoritma çalıştırmama yardım edebilir misin?" Elbette! Ona CUDA, CMake, Linux oluşturma, test etme ve optimize etme konularından bahsettim; belki bir saat konuşarak geçirdim. Bunların hepsini çok kibar bir şekilde dinledi ama sonunda şöyle dedi: “Bunların hepsi çok ilginç ama benim çok özel bir sorum var. Yani bir fonksiyonum var, tanımından önce @cuda.jit yazdım ve Python diziler hakkında bir şeyler söylüyor ve çekirdeği derlemiyor. Buradaki sorunun ne olabileceğini biliyor musun?”
Bilmiyordum. Bunu bir günde kendisi çözdü. Görünüşe göre Numba yerel Python listeleriyle çalışmıyor, yalnızca NumPy dizilerindeki verileri kabul ediyor. Böylece bunu anladı ve algoritmasını GPU'da çalıştırdı. Python'da. Aylardır uğraştığım sorunların hiçbiri onda yoktu. Bunu Linux'ta mı istiyorsunuz? Sorun değil, sadece Linux'ta çalıştırın. Python koduyla tutarlı olmasını istiyor musunuz? Sorun değil, Python kodu. Hedef platform için optimizasyon yapmak ister misiniz? Yine sorun değil. Numba, önceden derlenmediğinden, kodu çalıştırdığınız platform için kodu optimize edecektir; zaten dağıtıldığında talep üzerine derler.
Harika değil mi? Hayır. Zaten benim için değil. Numba'da asla meydana gelmeyen sorunları çözmek için C++ ile aylar harcadım ve Bremen'den yarı zamanlı bir çalışan aynı şeyi birkaç gün içinde yaptı. Numba'yla ilk deneyimi olmasaydı birkaç saat sürebilirdi. Peki nedir bu Numba? Bu nasıl bir büyü?
Büyü yok. Python dekoratörleri her kod parçasını sizin için soyut sözdizimi ağacına dönüştürür, böylece onunla istediğiniz her şeyi yapabilirsiniz. Numba, sahip olduğu herhangi bir arka uçla ve desteklediği herhangi bir platform için soyut sözdizimi ağaçlarını derlemek isteyen bir Python kütüphanesidir. Python kodunuzu CPU çekirdekleri üzerinde büyük ölçüde paralel bir şekilde çalışacak şekilde derlemek istiyorsanız, Numba'ya bunu bu şekilde derlemesini söylemeniz yeterli. Yine GPU üzerinde bir şey çalıştırmak istiyorsanız yalnızca sormalısınız .
@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
Numba, C++'ı geçersiz kılan Python derleyicilerinden biridir. Ancak teoride aynı arka uçları kullandığından C++'dan daha iyi değildir. GPU programlama için CUDA'yı ve CPU için LLVM'yi kullanır. Uygulamada, her yeni mimari için önceden yeniden yapılanma gerektirmediğinden, Numba çözümleri her yeni donanıma ve mevcut optimizasyonlara daha iyi uyum sağlar.
Elbette Spiral'de olduğu gibi net bir performans avantajına sahip olmak daha iyi olacaktır. Ancak Spiral daha çok bir araştırma projesidir, C++'ı öldürebilir, ancak eninde sonunda ve yalnızca şanslıysa. Python'lu Numba şu anda gerçek zamanlı olarak C++'ı boğuyor. Çünkü Python'da yazabiliyorsanız ve C++ performansına sahipseniz neden C++ ile yazmak isteyesiniz ki?
Hadi başka bir oyun oynayalım. Size üç parça kod vereceğim ve bunlardan hangisinin veya belki daha fazlasının montajda yazıldığını tahmin edeceksiniz. İşte buradalar:
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
(module (func $add (param $lhs i32) (param $rhs i32) (result i32) get_local $lhs get_local $rhs i32.add) (export "add" (func $add)))
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 }
Peki hangisi veya birden fazlası toplantıda? Üçünün birden olduğunu düşünüyorsanız tebrikler! sezgileriniz şimdiden çok daha iyi hale geldi!
İlki MASM32'de. Bu, insanların yerel Windows uygulamalarını yazdığı "if" ve "while"ların bulunduğu bir makrobirleştiricidir. Bu doğru, "eskiden yazardı" değil, bugüne kadar "yazıyordu". Microsoft, Windows'un Win32 API ile geriye dönük uyumluluğunu büyük bir gayretle korur, böylece şimdiye kadar yazılan tüm MASM32 programları modern bilgisayarlarda da iyi çalışır.
İronik olan C, UNIX'in PDP-7'den PDP-11'e çevirisini kolaylaştırmak için icat edildi. 70'lerin donanım mimarilerinin Kambriyen patlamasına dayanabilecek taşınabilir bir montajcı olarak tasarlandı. Ancak 21. yüzyılda donanım mimarisi o kadar yavaş gelişiyor ki, 20 yıl önce MASM32'de yazdığım programlar bugün mükemmel bir şekilde bir araya getiriliyor ve çalışıyor, ancak geçen yıl CMake 3.21 ile oluşturduğum bir C++ uygulamasının bugün CMake ile oluşturulacağına dair hiçbir güvenim yok. 3.25.
İkinci kod parçası Web Assembly'dir. Bir makro birleştirici bile değil, "if" ve "while" ifadeleri yok, daha çok tarayıcınız için insanlar tarafından okunabilen bir makine kodu. Veya başka bir tarayıcı. Kavramsal olarak herhangi bir tarayıcı.
Web Assembly kodu hiçbir şekilde donanım mimarinize bağlı değildir. Hizmet ettiği makine soyuttur, sanaldır, evrenseldir, ona ne derseniz deyin. Bu metni okuyabiliyorsanız, fiziksel makinenizde zaten bir tane var demektir.
Ancak kodun en ilginç parçası üçüncüsüdür. C++ ve montaj optimizasyon kılavuzlarının ünlü yazarı Agner Fog, ForwardCom'un önerdiği bir montajcıdır. Tıpkı Web Assembly'de olduğu gibi, öneri bir montajcıdan çok, yalnızca geriye dönük değil ileriye dönük uyumluluğu da mümkün kılmak için tasarlanmış evrensel talimatlar kümesini kapsar. Dolayısıyla adı. ForwardCom'un tam adı “ ileriye dönük açık bir komut seti mimarisi ”dir. Başka bir deyişle, bu bir barış antlaşması teklifi olarak bir toplantı teklifi değil.
En yaygın mimari ailelerin hepsinin: x64, ARM ve RISC-V'nin farklı komut setlerine sahip olduğunu biliyoruz. Ancak hiç kimse bu şekilde kalmasının iyi bir nedenini bilmiyor. Belki de en basiti hariç tüm modern işlemciler, onu beslediğiniz kodu değil, girdinizi çevirdikleri mikro kodu çalıştırır. Yani Intel için geriye dönük uyumluluk katmanına sahip olan yalnızca M1 değil, her işlemcinin aslında önceki tüm sürümleri için bir geriye dönük uyumluluk katmanı vardır.
Peki mimari tasarımcıların ileriye yönelik uyumluluk dışında benzer bir katman üzerinde anlaşmasını engelleyen şey nedir? Doğrudan rekabet halindeki şirketlerin çatışan hırsları dışında hiçbir şey yok. Ancak işlemci üreticileri bir noktada her rakip için yeni bir uyumluluk katmanı uygulamak yerine ortak bir talimat setine sahip olmaya karar verirlerse ForwardCom montaj programlamasını ana akıma geri döndürecektir. Bu ileri uyumluluk katmanı, her montaj programcısının en kötü nevrozunu iyileştirecektir: "Ya bu belirli mimari için ömür boyu bir kod yazarsam ve bu özel mimari bir yıl içinde kendini geçersiz kılarsa?"
İleriye dönük uyumluluk katmanıyla kendisini asla eskitmeyecek. Önemli olan bu.
Montaj programlaması aynı zamanda montajda yazmanın zor ve dolayısıyla pratik olmadığı yönündeki bir efsane tarafından da engelleniyor. Fog'un önerisi bu soruna da değiniyor. Eğer insanlar derlemede yazmanın zor olduğunu ve C'de yazmanın zor olduğunu düşünüyorsa, hadi birleştiriciyi C'ye benzetelim. Sorun değil. Modern bir montaj dilinin, büyükbabasının 50'li yıllardaki görünümüyle tamamen aynı görünmesi için iyi bir neden yoktur.
Az önce üç montaj örneğini kendiniz gördünüz. Hiçbiri “geleneksel” bir meclise benzemiyor ve olmamalı da.
Yani ForwardCom, hiçbir zaman modası geçmeyecek en uygun kodu yazabileceğiniz ve “geleneksel” bir montajı öğrenmenizi sağlamayan bir montajdır. Tüm pratik hususlar açısından, geleceğin C'sidir. C++ değil.
Postmodern bir dünyada yaşıyoruz. Artık insanlardan başka hiçbir şey ölmüyor. Tıpkı COBOL, Algol 68 ve Ada gibi Latince'nin aslında hiç ölmemesi gibi, C++ da yaşamla ölüm arasındaki sonsuz yarı varoluşa mahkumdur. C++ aslında hiçbir zaman ölmeyecek, yalnızca daha yeni ve daha güçlü teknolojiler tarafından ana akımdan uzaklaştırılacak.
Yani “itilecek” değil, “itilecek”. Şu anki işime C++ programcısı olarak geldim ve bugün iş günüm Python ile başlıyor. Ben denklemleri yazıyorum, SymPy bunları benim için çözüyor ve ardından çözümü C++'a çeviriyor. Daha sonra bu kodu C++ kitaplığına yapıştırıyorum, biraz biçimlendirme zahmetine bile girmiyorum çünkü clang-tidy zaten bunu benim için yapacak. Statik bir analizör, ad alanlarını bozmadığımı kontrol edecek ve dinamik bir analizör, bellek sızıntılarını kontrol edecektir. CI/CD platformlar arası derlemeyle ilgilenecektir. Bir profil oluşturucu, kodumun gerçekte nasıl çalıştığını ve ayrıştırıcının nedenini anlamama yardımcı olacaktır.
Eğer C++'ı "C++ değil" ile değiştirirsem işimin %80'i tamamen aynı kalacaktır. C++ yaptığım çoğu şeyle alakasız. Bu benim için C++'ın zaten %80 ölü olduğu anlamına mı geliyor?
Kararlı difüzyonla geliştirilen kurşun görüntüsü.