Comment réussir la programmation système, ce que vous devez savoir et comprendre, surtout si vous travaillez depuis la troisième décennie? C # et performances - cela vaut-il la peine de réécrire tout ce que vous voyez en C #? Quel avenir pour les technologies de compilation de bas niveau qui nous attendent?
Aujourd'hui dans notre studio virtuel,
Alexandre Mutel répond aux questions.

Alexandre Mutel est architecte logiciel principal chez Unity Technologies. De plus, il est un développeur open source bien connu contribuant à SharpDX, Markdig, Zio et à d'autres projets, et depuis 2014 - MVP dans la catégorie Visual Studio et Technologies de développement.
Alexandre travaille sur une variété de problèmes de bas et de haut niveau dans le rendu graphique en temps réel, le GPGPU, la synthèse sonore, l'utilisation efficace et l'architecture des langages gérés, la génération de code et la documentation.
Comme toujours, les interviews sont menées par Evgeny Trifonov (
phillennium ) et Oleg Chirukhin (
olegchir ) du groupe JUG.ru.

À la fin de l'article, il y a une surprise de Dylan Beatty (un autre donateur célèbre) - nous-mêmes, nous ne nous y attendions pas.
E.: Vous avez une longue carrière, trois décennies - pour commencer, pouvez-vous en parler brièvement?Tout a commencé dans l'enfance - j'ai eu Amstrad PC 464. Quand j'ai commencé à programmer sur cet ordinateur, j'avais 11 ou 12 ans, je ne me souviens pas exactement. J'ai rapidement maîtrisé la programmation BASIC et acheté des livres sur le développement de jeux: cela m'a paru très intéressant. J'ai joué très peu de jeux, où il était plus intéressant de développer et d'écrire du code. Ensuite, j'ai continué à écrire du code assembleur pour Amstrad.
À 16 ans, j'ai eu un Amiga 500. J'ai rencontré des gars qui écrivaient des démos - ce n'était plus du tout ce que c'est maintenant. Maintenant, c'est WebGL, et c'est une demoscène complètement différente. J'ai commencé à écrire beaucoup de démos, que je ne montrais pas toujours, mais j'aimais juste écrire en assembleur. Et c'était aussi simple que cela.
Il est ensuite allé à un collège technologique, où il a étudié le génie informatique. C'était déjà quelque chose de complètement différent par rapport aux jeux et à l'assembleur. J'ai adoré apprendre des choses dont je ne savais même pas qu'elles existaient auparavant: les systèmes d'exploitation, UNIX, travailler avec le langage C (avant cela, je n'utilisais que BASIC ou l'assembleur parce que je n'avais pas l'argent pour acheter un compilateur C / C ++).
Après avoir obtenu son diplôme universitaire, il a commencé à travailler dans l'industrie du marché des devises. C'était un travail pour une entreprise française à New York. Deux ans plus tard, je suis revenu et suis allé à la banque. En fait, je ne voulais pas travailler dans une banque, je voulais travailler dans le développement de jeux. Mais en conséquence, coincé il y a un nouveau domaine, beaucoup de choses peuvent être apprises. J'ai donc passé 8 à 9 ans là-bas, principalement avec Java et un peu avec C ++. Beaucoup de serveurs distribués et de bases de données SQL, copie de bases de données ... Pas du tout ce que je fais maintenant.
Puis j'ai pris un congé créatif et j'ai fait un voyage touristique à travers le monde: j'étais en Afrique, en Amérique du Sud, toute une année en Asie. Le voyage m'a changé et m'a secoué. À mon retour, je ne pouvais plus travailler avec des ordinateurs, dans le domaine informatique, je ne pouvais pas travailler pour la banque. J'ai quitté mon emploi et j'ai passé 4 ans dans des cours de travailleur social pour travailler avec les enfants, les sans-abri, les handicapés, les personnes âgées. J'ai étudié cela pendant trois ans, et c'était très intéressant, car la majeure partie de ma vie j'ai travaillé dans le domaine des sciences exactes: mathématiques, projets, abstractions. Et puis il a soudainement pris et déménagé dans une zone très humanitaire. J'ai même essayé de travailler dans ce domaine après l'entraînement, mais juste pendant cette période, un ami avec qui j'ai fait des démos enfant a laissé entendre que nous pouvions recommencer.
J'ai commencé à pratiquer des démos tout mon temps libre, et très vite, cela a commencé à prendre plus que de travailler avec des enfants dans la rue. C'était mauvais. Les gens ont dit: «Nous devons essayer de trouver du travail dans le développement de jeux, pourquoi pas? Vous pouvez le faire. " Mais je pensais que c'était impossible, car je n'avais pas travaillé avec les ordinateurs depuis longtemps, et il était difficile de trouver du travail en informatique avec mon CV.
J'ai commencé à travailler sur des applications open source et j'ai publié quelques projets que les entreprises ont commencé à utiliser. Une fois, l'une de ces sociétés m'a contacté, elle a utilisé l'un des derniers projets appelé SharpDX. Je suis allé au Japon avec ma famille - parce que j'avais déjà deux enfants. Nous avons vécu 5 ans au Japon. A cette époque, je travaillais sur la création d'un moteur de jeu à partir de zéro en C #.
Il y a environ deux ans, je suis rentré en France et j'ai commencé à travailler chez Unity. Cela a interféré avec ce que j'ai fait auparavant, mais ils ont proposé de travailler sur une tâche très complexe et intéressante, un vrai test: créer un compilateur natif qui génère du code natif à partir du code IL .NET. C'est exactement ce que j'ai toujours voulu faire, mais je ne pouvais pas, car je n'aurais pas été payé pour cela. Et puis il y avait une chance, une grande opportunité. J'ai travaillé sur ce projet pendant 2 ans.
Oui, il semble que l'histoire ne soit pas très courte.
E.: Rien, une telle carrière vaut une longue histoire. En raison de votre expérience, je voudrais vous poser cette question. Maintenant, certaines personnes disent: "La loi de Moore ne fonctionne plus, les ordinateurs ne vont pas plus vite, nous sommes tous condamnés." D'autres répondent: «Allez, bien qu'ils n'accélèrent pas au même rythme, il y a toujours de la croissance, donc il n'y a pas de raison de paniquer.» Étant donné que le thème de la productivité est proche de vous et que vous suivez l'industrie depuis longtemps, quelle est votre position?J'adhère à ce juste milieu.
(rires) Je pense que de nombreuses applications, si ce n'est la plupart, que nous développons s'adaptent aux exigences de performance dès le début, ce qui se traduit par la meilleure qualité possible.
Voyez ce qui s'est passé dans l'industrie informatique sous nos yeux. Par exemple, lorsque Windows est devenu un peu plus lent au fil des ans - Windows Vista, etc. En fait, un travail naturel a été fait pour améliorer les performances, car pendant des années il n'a pas été particulièrement inquiété. Lorsque Windows 8 est sorti, c'était déjà un peu mieux. Ensuite, Windows 10 est sorti et cela s'est un peu amélioré. En conséquence, nous avons un système qui fonctionne assez bien par rapport à ce qu'il était auparavant. Il était vraiment important pour eux de faire ces optimisations, car une fois les gens «vivraient nécessairement au-dessus de leurs moyens» et commenceraient à dire: «Oh! Ce logiciel ne fonctionne plus, nous passons à Linux, car il est plus rapide et moins stupide. "
On peut en dire autant de tous les logiciels que nous développons. Et ce qui est surprenant: il y a toujours eu une tendance à travailler avec du code natif, à un moment donné même sous Windows, ils ont décidé de revenir en C ++, ils ont dit: "C ++ est une solution, .NET est très lent, puis Garbage Collector et blah blah blah ... ". Et encore une fois, les langues maternelles sont devenues pertinentes.
Dans le même temps, V8 dans Chrome a réactivé JavaScript grâce à JIT. JS est un langage de script, pas ultra-rapide, mais parfois il fonctionne deux fois plus vite que C ++. Cela lui suffisait pour survivre et pour nous de l'utiliser dès maintenant pour des choses comme l'écriture de code dans Visual Studio Code. Mais si vous regardez de près, c'est parce que les exigences de performance y ont été fixées dès le début. Même dans VSCode, même s'il y a beaucoup de code JavaScript et de script en général, tout le reste - V8, pile de rendu, JIT - tout cela est écrit dans un langage conçu pour des performances maximales, c'est-à-dire en C ++. Tout pourrait être écrit dans un autre langage, pas nécessairement en C ++, mais le fait est que tous ces logiciels ont été développés en tenant compte des performances dès le début.
Alors oui, nous pouvons utiliser des langages moins efficaces et moins productifs, mais uniquement parce que toutes les technologies sous-jacentes sont développées dans le but de gagner une
expérience utilisateur fantastique. Par exemple, Visual Studio Code est un logiciel incroyable qui fonctionne très bien pour les développeurs et résout leurs problèmes. Beaucoup de gens disent: «Bien que nous aimions utiliser davantage d'éditeurs de code natifs, nous passons actuellement à Visual Studio Code» - car ils le considèrent très efficace. Les performances sont partout, mais parfois nous ne les voyons pas car elles sont déjà intégrées dans tout ce que nous utilisons.
Nous pensons: il est écrit en JavaScript, car il est assez rapide. Mais JavaScript est si rapide simplement parce que des centaines de centaines d'ingénieurs de développement ont travaillé pendant des années pour optimiser JIT. Nous pouvons maintenant utiliser des langages de script même pour écrire des applications très complexes. Langages de script qui, sans tout ce travail préparatoire, auraient été beaucoup plus lents. Nous vivons dans des temps étranges. Nous avons le choix, mais il y a toujours cette histoire de performance qui se répète encore et encore pour chaque langue.
Donc .NET est un exemple typique. Un énorme travail y a été accompli au cours des trois à quatre dernières années. Si vous regardez ASP.NET Core un jour, si vous regardez tout le travail effectué avec CoreCLR ... Les performances sont une bonne chose à vendre, elles coûtent de l'argent et vous permettent d'en faire plus. En essayant de répondre à des exigences strictes, vous pouvez essayer de devenir plus productif, vous pouvez économiser de l'énergie, économiser de l'argent à la fin du mois - les performances affectent tout. Quand j'entends des gens dire: "Tout est en ordre, je développe mon application, elle a des performances moyennes, ça va faire ...", qu'en pensent-ils? Vous devez prendre un peu de temps pour vérifier si vous pouvez rendre votre application un peu plus productive. Si vous pouvez économiser au moins un dixième de ressources ou de temps d'application, c'est bien.
E.: Il y a en partie une question philosophique. Vous pensez que Slack n'est pas le meilleur endroit pour les solutions techniques, mais sur votre site, vous proposez de vous abonner au RSS old-school. Pensez-vous que la nouvelle ère de la messagerie instantanée rend les développeurs moins productifs?Non, je ne pense pas. Maintenant, je travaille à distance. Au travail, chez Unity, nous pouvons travailler à distance, donc j'utilise constamment Slack pour communiquer avec mes collègues. C'est le meilleur moyen pour moi d'être en contact et de rester productif. Cela prend beaucoup de temps de travail, car vous devez vérifier les chaînes, etc., mais je peux temporairement désactiver Slack et me concentrer sur le travail. Alors que je travaillais dans l'entreprise en open space, je n'avais pas le choix: si quelqu'un veut poser une question, il faut y répondre tout de suite, c'est beaucoup plus compliqué.
Quant à Twitter et au courrier électronique, je ne les vérifie pas si souvent. Une ou deux fois par jour, je lis Twitter, cela dépend de divers facteurs: si je participe à des discussions et de quoi je discute. Si vous utilisez quelque chose comme Slack, vous pouvez rejoindre différents canaux dans l'entreprise, vous pouvez suivre de nombreux sujets que vous ne pourriez pas suivre si vous travailliez seul. Nous devons trouver un terrain d'entente: nous nous inquiétons tous de beaucoup de choses qui se produisent dans l'entreprise, mais nous devons être sélectifs, car vous ne pouvez pas participer à toutes les discussions en même temps. Certaines personnes peuvent lire tellement de chaînes que je suis simplement étonné de leurs capacités, je ne suis pas moi-même comme ça. Aujourd'hui, j'ai lu environ 30 chaînes, ce n'est pas tellement.
E.: Merci, il est temps pour les questions d’Oleg!A.: Ma carrière est quelque peu similaire à la vôtre: j'ai travaillé dans une banque, maintenant dans un domaine complètement différent - dans l'organisation de conférences, et en même temps j'essaie de comprendre comment construire des compilateurs. Que pouvez-vous conseiller à ceux qui essaient de passer à la programmation système de simples développeurs Web d'entreprise, existe-t-il des conseils pour une telle transition? Je suis sûr qu'il n'y en a pas assez ici, assez.Je ne sais pas s'il existe un chemin préparé pour une telle transition. Si vous êtes intéressé par ces technologies, vous faites des devoirs ordinaires. À la maison, vous écrivez des analyseurs et des choses liées aux compilateurs. Il n'est pas nécessaire d'écrire l'intégralité du compilateur du début à la fin, jusqu'à la génération même du code machine. Vous vous intéressez à l'écriture de l'infrastructure du compilateur. C'est ce que j'ai fait ces dernières années en travaillant chez Unity. Si vous êtes passionné par les choses de bas niveau, alors c'est l'un de ces endroits où vous pouvez comprendre comment tout cela fonctionne dans la réalité. Comment améliorer le travail, où cela vaut la peine d'améliorer les performances et où cela n'a pas encore été fait. Si vous êtes préoccupé par les performances, il est très important de savoir sur quoi l'application s'exécutera à la fin.
La performance est mon thème, et tout cela est devenu une grande opportunité pour moi. Je voudrais aborder la solution du problème à sa base, c'est-à-dire au niveau du compilateur. C'est ici que nous pouvons augmenter la productivité des dizaines de fois dans les endroits où cela est nécessaire pour nos utilisateurs. Si nous exécutons des jeux, des applications, des films ou quelque chose comme ça, il peut parfois être relativement facile d'obtenir de tels résultats.
Ma passion pour les choses de bas niveau et les composants de compilateur m'a conduit à mon travail actuel. Mais ce n'était pas quelque chose que je voulais spécifiquement faire. Parfois, lorsque vous acquérez beaucoup d'expérience avec différentes langues, vous écrivez des applications - vous voulez même créer votre propre langue. J'ai commencé à faire ça, mais j'ai arrêté parce que c'est trop de travail et j'ai très peu de temps libre. Mais vous avez un désir subconscient de retourner "aux racines", essayez de faire quelque chose vous-même pour tout comprendre. Bien sûr, j'ai compris le fonctionnement des compilateurs et tout ça, mais je n'ai pas compris la complexité des exigences. Des compromis complexes à traiter, par exemple, dans le domaine de la gestion de la mémoire. Il est très difficile de choisir ce qui en même temps donnera une plus grande productivité du développeur d'application et sera efficace. Ce problème n'est toujours pas résolu jusqu'à la fin. Rust ou .NET ne résoudra jamais cela. La rouille est belle, incroyable, mais elle est difficile à travailler, surtout si vous passez à elle avec quelque chose comme JavaScript. Cependant, il existe des exemples de développeurs Python ou JavaScript qui migrent vers Rust, bien que cela soit quelque peu surprenant.
R: Vous avez mentionné que vous avez programmé en C # au cours des 10 dernières années. Alors, qu'est-ce qui est bon en C #? Pourquoi pas C ++, par exemple? Le C ++ semble être un langage plus systémique.Pour être honnête, je déteste le C ++, je déteste le C, mais je travaille avec eux. Je crois sincèrement qu'ils conduisent à un tas de bugs, à une énorme inefficacité de développement. Beaucoup de gens pensent que puisque vous programmez en C, vous écrivez déjà de facto du code rapide pour que votre programme soit orienté vers les performances. Ce n'est pas vrai. Si vous sculptez des tas de malloc et tout cela, cela sera lent même par rapport à ce qui est écrit en .NET. Les bons développeurs C / C ++ sont obligés d'utiliser des astuces comme l'
allocateur de mémoire de région . Vous devez vous enterrer dans un tas de choses étranges dont personne n'a entendu parler. Bien qu'ici, les développeurs de jeux connaissent généralement de telles choses. Au minimum, des développeurs AAA ou des personnes qui créent des jeux dans des frameworks C / C ++. Certains problèmes découlent de la complexité de la langue elle-même. Avant, je ne lisais pas du tout de livres sur C ++, et il y a seulement trois ou quatre ans, j'ai commencé à lire des livres uniquement sur C ++, juste pour ressentir le langage. Je l'ai programmé, mais je n'ai pas eu d'approche systématique et formelle, et j'ai été frappé par sa complexité, le nombre de choses que vous pouvez ruiner si vous n'écrivez pas tout correctement.
Il y a quelques mois à peine, il y avait un bogue dans Unity, quelqu'un a fait une erreur dans un morceau de code C ++, c'était dans le constructeur, quelque chose a été passé par valeur, et en conséquence, nous avons pris l'adresse de cette valeur et regardé dans le cache. En fait, nous avons fait référence à une valeur qui n'était plus dans la mémoire. Et tout cela parce que les pointeurs étaient mélangés avec des non-indicateurs, et celui qui a fait ce refactoring n'a pas vérifié tous les lieux d'utilisation. Un code complètement différent qui fonctionnait parfaitement a soudainement cessé de fonctionner. Cela semble être une petite erreur, mais cela a tout cassé. En fait, c'est une erreur de travailler avec la mémoire. Alors oui, quand je vois de telles choses, je suis convaincu que nous devons restreindre l'accès au travail en C et C ++, et minimiser leur utilisation. Dans la partie .NET, j'ai vraiment limité leur utilisation aux seules choses spécifiques à la plate-forme. Mais tout écrire en C # est assez morne. Pour accéder à l'API, vous devez faire un tas de dlopen. Bien que, par exemple, vous puissiez essayer d'encapsuler tout cela dans un wrapper en C et d'organiser l'accès via une seule fonction. Je préfère isoler ces choses et les développer davantage en C et C ++. Mais c'est un sujet tellement étroit sur l'interopérabilité, et ensuite vous restez avec un langage contrôlé normal, l'utilisez la plupart du temps, profitez d'une compilation plus rapide.
Je déteste les erreurs du compilateur et de l'éditeur de liens C ++, je déteste la nécessité de travailler avec différentes plates-formes, tout cela est très, très difficile. Vous commencez à compiler sur MSVC, puis vous devez passer à Clang, puis à GCC. Sous Linux, Mac, Windows, Android, iOS et ainsi de suite. Travailler avec C ++ est un cauchemar!
Je déteste la séparation entre les fichiers de l'éditeur, les fichiers .h et les fichiers cpp. Les gens sont complètement confus dans la langue et commencent à programmer sur des macros. J'adore la métaprogrammation, mais en C ++ moderne, nous pouvons faire une folie complète. En soi, ces choses sont incroyables, mais en fait c'est déjà trop.
Pour résumer: oui, je pense que nous pouvons développer des logiciels efficaces en C #. Peut-être pas aussi vite qu'en C ++, mais nous le pouvons. C'est exactement ce que nous essayons de faire dans Unity - par exemple, nous faisons un compilateur de rafales pour compiler un sous-ensemble particulier de C #, obtenant des performances maximales, encore plus à certains endroits que ce qui se serait produit en C ++ - mais restant en C #. C'est complètement sûr. Pour les pointeurs, vous devez déclarer dangereux, ne pas lever d'exceptions, tout faire explicitement. Et c'est une expérience amère. Mais vous pouvez toujours écrire du code qui sera aussi rapide qu'en C ++. Je pense que c'est exactement la direction dans laquelle .NET vaut la peine d'aller et où nous devrions aller.
R: Si nous parlons de code open source, par exemple, nous avons un garbage collector dans .NET Core, qui est un fichier C très volumineux et effrayant. Deux mégaoctets d'ordures, probablement générés par une sorte de lisp (à peine autant de lettres valaient la peine d'être écrites manuellement). Peut-être qu'il est logique de tout réécrire ici en C #?Oui! Je discute avec des personnes qui travaillent sur JIT chez Microsoft et dans la communauté. Il y a quelque chose en quoi je crois vraiment. Je crois qu'il y a un moment où votre langue devient plus mature et fondamentale, et ensuite vous devez vous mettre au défi, la tester. Vous devez pouvoir l'utiliser comme fondation. Prouvez que vous pouvez même l'utiliser pour créer quelque chose de très exigeant sur les performances. Et c'est l'histoire de Garbage Collector et JIT. Un très, très grand pourcentage de sous-systèmes d'exécution .NET, y compris JIT et GC, peut être effectué en C #. Si vous établissez une règle selon laquelle en C ++ vous ne pouvez décrire que les abstractions de la plate-forme de base, cela rendra la plupart de la plate-forme d'exécution indépendante. Je serais très heureux si cela se produisait. Mais c'est un travail énorme.
Il y a une raison pour laquelle j'aime particulièrement cette idée. , C/C++ , - . , . - , IDE , , — . C#, . , , . . , , , CoreRT C# C++. .
, .NET GC C#. . , , .NET GC, -. GC, , - GC. Java- Jikes RVM — Java. , Golang C, Golang. Golang-, , . , , , . , . LLVM, .NET JIT.
, , .
.: , . — . , AST- . Golang , . , ? ?, , ! , . : . : -, .
: , , , , . , : « ! !». . , .
LLVM, — , . , , , , , . . , , . , . , , , , ? , , , . , - : «, , , - » — , , , .
, . , , , , , , - . , : , , . , , . , , . , . , — .
— . -. , -, API, . . , SharpDX . . , , , . DirectX C++ API, C++. , . , - , . : , . , SharpDX. , PR, . pull request ( ). - . - , SharpDX - . : « ?» ( , ) , . 90- — . , , .
, , , , : , , .
.: — , ? . , , ?, — , SIMD. , , SIMD , . ( LLVM, , ). , , . , , , . - , . , . . - Intel LLVM. , , LLVM. , , . LLVM — , , , .NET. SIMD, CPU — . , , .NET — SIMD- . , , .
: « ». . . LLVM : -, , . , , Roslyn C#, . , , . , , , . SIMD — . GPU, CPU, — . 6, 8, 16, 42 . - , , .
.: Markdown Markdig, ? , Markdown? , ?, Markdown — , . , , Word - . . ? , , . . , RFC — , , , . , , . , ASCII-art. Word, PDF . Word. - — . , . Markdown, , - — , HTML. , . HTML, Markdown . , Github, Markdown- . . — . , Microsoft Markdown, GitHub, PR — , .
Markdown, CommonMark, , Markdown. , CommonMark — . , , . ,
Github CommonMark . — . . Microsoft CommonMark, Markdig. , Markdig , Markdown-, . , , , CommonMark, Markdig. , . Markdig , , , . , Microsoft .
.: , ? ?, . — , . . , . , , , . , . « , , ». , ? , , , , , - . , Google « X» « ». , — . , , , . , , - — , . « , - ?»
, , . . , , . , - . , , , . — , , ? , ? , .
, . . ? ? , , . , … - , . . , , , .
. . ! , . — . , — - . , , , . , , , . , . , . . , - : « !». -, , , . , . .
, , , , , , , - , .
Vendredi prochain, Alexandra fera une présentation «Derrière le compilateur de rafales, convertissant .NET IL en code natif hautement optimisé en utilisant LLVM» à DotNext 2018 Moscou . La conférence se tiendra du 22 au 23 novembre à Moscou et, semble-t-il, ce sera le plus grand DotNext de tous. Nous vous dirions à quoi d'autre vous attendre de la conférence, mais cela a été mieux fait pour nous par son autre orateur, Dylan Beatty - il a enregistré toute la chanson: