“No seas tímido. ¡Pruébalo! Entrevistas sobre la vida, compiladores y la vida en compiladores con Unity Alexandre Mutel

¿Cómo tener éxito en la programación del sistema, lo que necesita saber y comprender, especialmente si ha estado trabajando durante la tercera década? C # y rendimiento: ¿vale la pena volver a escribir todo lo que ves en C #? ¿Cuál es el futuro de las tecnologías de compilación de bajo nivel que nos esperan?

Hoy en nuestro estudio virtual, Alexandre Mutel responde preguntas.

Alexandre Mutel es arquitecto principal de software en Unity Technologies. Además, es un conocido desarrollador de código abierto que contribuye a SharpDX, Markdig, Zio y otros proyectos y, desde 2014, MVP en la categoría de Visual Studio y Tecnologías de desarrollo.

Alexandre trabaja en una variedad de problemas de bajo y alto nivel en las áreas de representación gráfica en tiempo real, GPGPU, síntesis de sonido, uso eficiente y arquitectura de lenguajes administrados, generación de código y documentación.

Como siempre, las entrevistas son realizadas por Evgeny Trifonov ( phillennium ) y Oleg Chirukhin ( olegchir ) del Grupo JUG.ru.



Al final de la publicación hay una sorpresa de Dylan Beatty (otro donante famoso): nosotros mismos no lo esperábamos.

E .: Tienes una larga carrera, tres décadas. Para empezar, ¿puedes hablar brevemente sobre eso?

Todo comenzó en la infancia: obtuve Amstrad PC 464. Cuando comencé a programar en esta computadora, tenía 11 o 12 años, no recuerdo exactamente. Rápidamente dominé la programación BÁSICA y compré libros sobre desarrollo de juegos: luego me pareció muy interesante. Jugué muy pocos juegos, donde fue más interesante desarrollar y escribir código. Luego continué escribiendo código de ensamblador para Amstrad.

A los 16 años, obtuve un Amiga 500. Conocí a muchachos que escribían demos, no era para nada lo que es ahora. Ahora bien, esto es WebGL, y este es un demoscene completamente diferente. Comencé a escribir muchas demos, que no siempre mostraba, pero me gustaba escribir en ensamblador. Y fue así de simple.

Luego fue a una universidad tecnológica, donde estudió ingeniería informática. Esto ya era algo completamente diferente en comparación con los juegos y el ensamblador. Me encantaba aprender cosas que ni siquiera sabía que existían antes: sistemas operativos, UNIX, trabajar con el lenguaje C (antes solo usaba BASIC o ensamblador porque no tenía el dinero para comprar un compilador C / C ++).

Cuando se graduó de la universidad, comenzó a trabajar en la industria del mercado de divisas. Este era un trabajo para una empresa francesa en Nueva York. Dos años después, regresé y fui al banco. En realidad, no quería trabajar en un banco, quería trabajar en desarrollo de juegos. Pero como resultado, atascado hay una nueva área, se pueden aprender muchas cosas. Así que pasé 8-9 años allí, principalmente tratando con Java y un poco con C ++. Una gran cantidad de servidores distribuidos y bases de datos SQL, copiando bases de datos ... Para nada lo que estoy haciendo ahora.

Luego tomé un permiso creativo y realicé un viaje turístico alrededor del mundo: estuve en África, en América del Sur, todo un año en Asia. El viaje me cambió y me sacudió. Cuando regresé, ya no podía trabajar con computadoras, en el ámbito de TI, no podía trabajar para el banco. Renuncié a mi trabajo y pasé 4 años en cursos de trabajadores sociales para trabajar con niños, personas sin hogar, discapacitados, ancianos. Estudié esto durante tres años, y fue muy interesante, porque la mayor parte de mi vida trabajé en el campo de las ciencias exactas: matemáticas, proyectos, abstracciones. Y luego, de repente, tomó y se mudó a un área muy humanitaria. Incluso intenté trabajar en esta área después del entrenamiento, pero solo durante este período, un amigo con el que hice demostraciones cuando era niño insinuó que podemos hacerlo nuevamente.

Comencé a practicar demos todo mi tiempo libre, y muy rápidamente comenzó a tomar más que trabajar con niños en la calle. Eso estuvo mal. La gente decía: “Necesitamos tratar de encontrar trabajo en el desarrollo de juegos, ¿por qué no? Puedes hacerlo ". Pero pensé que esto era imposible, porque no había trabajado con computadoras durante mucho tiempo, y era difícil encontrar trabajo en TI con mi currículum.

Comencé a trabajar en aplicaciones de código abierto y lancé un par de proyectos que las empresas comenzaron a usar. Una vez, una de estas compañías se puso en contacto conmigo y utilizaron uno de los últimos proyectos llamado SharpDX. Fui a Japón con mi familia, porque ya tenía dos hijos. Vivimos 5 años en Japón. En este momento, estaba trabajando en crear un motor de juego desde cero en C #.

Hace unos dos años, regresé a Francia y comencé a trabajar en Unity. Esto interfirió con lo que hice antes, pero se ofrecieron a trabajar en una tarea muy compleja e interesante, una prueba real: hacer un compilador nativo que genere código nativo a partir del código IL .NET. Esto era exactamente lo que siempre quise hacer, pero no pude, porque no me habrían pagado por esto. Y luego hubo una oportunidad, una gran oportunidad. Trabajé en este proyecto durante 2 años.

Sí, parece que la historia no es muy corta.

E .: Nada, una carrera así vale una larga historia. Debido a su experiencia, me gustaría preguntarle esto. Ahora algunas personas dicen: "La Ley de Moore ya no funciona, las computadoras no son más rápidas, todos estamos condenados". Otros responden: "Vamos, aunque no están acelerando al mismo ritmo, todavía hay crecimiento, por lo que no hay razón para entrar en pánico". Dado que el tema de la productividad está cerca de usted y, al mismo tiempo, ha estado siguiendo a la industria durante mucho tiempo, ¿cuál es su posición?

Me adhiero a este medio dorado. (Risas) Creo que muchas, si no la mayoría de las aplicaciones que desarrollamos se adaptan a los requisitos de rendimiento desde el principio, lo que resulta en la mejor calidad posible.

Vea lo que sucedió en la industria de TI ante nuestros ojos. Por ejemplo, cuando Windows se volvió un poco más lento con los años: Windows Vista, etc. De hecho, se realizó un trabajo natural para mejorar el rendimiento, porque durante años no estuvo particularmente preocupado. Cuando salió Windows 8, ya estaba un poco mejor. Luego salió Windows 10 y mejoró un poco. Como resultado, tenemos un sistema que funciona bastante bien en comparación con lo que era antes. Fue realmente importante para ellos hacer estas optimizaciones, porque una vez las personas necesariamente "vivirían más allá de sus posibilidades" y comenzarían a decir: "¡Oh! Este software ya no funciona, estamos cambiando a Linux, porque es más rápido y menos estúpido ".

Lo mismo puede decirse de todo el software que desarrollamos. Y lo que es sorprendente: siempre ha habido una tendencia a trabajar con código nativo, en algún momento incluso en Windows decidieron volver a C ++, dijeron: "C ++ es una solución, .NET es muy lento, entonces Garbage Collector y bla bla bla ... ". Y nuevamente, los idiomas nativos se hicieron relevantes.

Al mismo tiempo, V8 en Chrome volvió a usar JavaScript gracias a JIT. JS es un lenguaje de script, no súper rápido, pero a veces funciona dos veces más rápido que C ++. Eso fue suficiente para que él sobreviviera y para que lo usemos ahora mismo para cosas como escribir código en Visual Studio Code. Pero si observa de cerca, todo se debe a que los requisitos de rendimiento se establecieron allí desde el principio. Incluso en VSCode, aunque hay una gran cantidad de código JavaScript y script en general, todo lo demás (V8, stack de renderizado, JIT) está escrito en un lenguaje diseñado para un rendimiento máximo, es decir, en C ++. Todo podría estar escrito en otro idioma, no necesariamente en C ++, pero el hecho es que todo este software se desarrolló teniendo en cuenta el rendimiento desde el principio.

Entonces, sí, podemos usar lenguajes menos eficientes y productivos, pero solo porque todas las tecnologías subyacentes se desarrollan con el objetivo de obtener una experiencia de usuario fantástica. Por ejemplo, Visual Studio Code es un software increíble que funciona muy bien para los desarrolladores y resuelve sus problemas. Mucha gente dice: "Aunque nos gusta usar más editores de código nativo, en este momento estamos cambiando a Visual Studio Code", porque lo consideran bastante efectivo. El rendimiento está en todas partes, pero a veces no lo vemos porque ya está incrustado en todo lo que usamos.

Pensamos: está escrito en JavaScript, porque es lo suficientemente rápido. Pero JavaScript es tan rápido solo porque cientos de cientos de ingenieros de desarrollo han trabajado durante años para optimizar JIT. Ahora podemos usar lenguajes de script incluso para escribir aplicaciones muy complejas. Lenguajes de script que sin todo este trabajo preparatorio hubieran sido mucho más lentos. Vivimos en tiempos extraños. Tenemos una opción, pero aún existe esta historia de rendimiento que se repite una y otra vez para cada idioma.

Entonces .NET es un ejemplo típico. Se ha realizado un gran trabajo allí durante los últimos tres o cuatro años. Si observa ASP.NET Core en algún momento, si observa todo el trabajo realizado con CoreCLR ... El rendimiento es una buena venta, cuesta dinero y le permite lograr más. Intentando cumplir requisitos estrictos, puede intentar ser más productivo, puede ahorrar energía, ahorrar dinero a fin de mes: el rendimiento afecta todo. Cuando escucho a la gente decir: "Todo está en orden, estoy desarrollando mi aplicación, tiene un rendimiento promedio, servirá ...", ¿qué están pensando? Debe tomarse un poco de tiempo para verificar si puede hacer que su aplicación sea un poco más productiva. Si puede ahorrar recursos o tiempo de aplicación al menos una décima parte, está bien.

E .: Hay en parte una pregunta filosófica. Cree que Slack no es el mejor lugar para soluciones técnicas, pero en su sitio ofrece suscribirse a RSS de la vieja escuela. ¿Crees que la nueva era de la mensajería instantánea está haciendo que los desarrolladores sean menos productivos?

No, no lo creo. Ahora trabajo de forma remota. En el trabajo, en Unity, podemos trabajar de forma remota, por lo que uso constantemente Slack para comunicarme con mis colegas. Esta es la mejor manera de estar en contacto y ser productivo. Esto lleva mucho tiempo del trabajo, porque necesitas revisar los canales, etc., pero puedo desactivar temporalmente Slack y enfocarme en el trabajo. Mientras trabajaba en la empresa en espacios abiertos, no tenía otra opción: si alguien quiere hacer una pregunta, debe responder de inmediato, es mucho más complicado.

En cuanto a Twitter y correo electrónico, no los reviso con tanta frecuencia. Una o dos veces al día leo Twitter, depende de varios factores: si participo en alguna discusión y qué discuto. Si usa algo como Slack, puede unirse a diferentes canales en la empresa, puede seguir muchos temas que no podría seguir si trabajara solo. Necesitamos encontrar un punto medio: todos nos preocupamos por muchas cosas que suceden en la empresa, pero debemos ser selectivos, porque no puede participar en todas las discusiones al mismo tiempo. Algunas personas pueden leer tantos canales que simplemente estoy asombrado de sus habilidades, yo mismo no soy así. Hoy leí unos 30 canales, esto no es tanto.

E .: Gracias, ¡es hora de las preguntas de Oleg!

R .: Mi carrera es algo similar a la suya: trabajé en un banco, ahora en un campo completamente diferente, organizando conferencias y, al mismo tiempo, estoy tratando de descubrir cómo construir compiladores. ¿Qué puede aconsejar a aquellos que intentan cambiar a la programación del sistema desde simples desarrolladores web empresariales? ¿Hay algún consejo para tal transición? Estoy seguro de que no hay suficientes de nosotros aquí, hasta suficientes.

No estoy seguro si hay un camino preparado para tal transición. Si estás interesado en tales tecnologías, entonces haces una tarea ordinaria. En casa, escribes analizadores y cosas relacionadas con compiladores. No es necesario escribir todo el compilador de principio a fin, hasta la generación misma del código de máquina. Te interesas en escribir la infraestructura del compilador. Esto es lo que he estado haciendo en los últimos años trabajando en Unity. Si te apasionan las cosas de bajo nivel, entonces este es uno de esos lugares donde puedes entender cómo funciona todo en realidad. Cómo mejorar el trabajo, dónde vale la pena mejorar el rendimiento y dónde aún no se ha hecho. Si le preocupa el rendimiento, es muy importante saber en qué se ejecutará la aplicación al final.

El rendimiento es mi tema, y ​​todo esto se ha convertido en una gran oportunidad para mí. Me gustaría abordar la solución del problema en su núcleo, es decir, en el nivel del compilador. Es aquí donde podemos aumentar la productividad decenas de veces en aquellos lugares donde es necesario para nuestros usuarios. Si ejecutamos juegos, aplicaciones, películas o algo así, a veces puede ser relativamente fácil lograr tales resultados.

Mi pasión por las cosas de bajo nivel y los componentes del compilador me llevaron a mi trabajo actual. Pero eso no era algo que específicamente quisiera hacer. A veces, cuando obtienes mucha experiencia con diferentes idiomas, escribes aplicaciones, incluso quieres crear tu propio idioma. Comencé a hacer esto, pero paré porque es demasiado trabajo y tengo muy poco tiempo libre. Pero tiene un deseo subconsciente de volver "a las raíces", intente hacer algo usted mismo para comprenderlo todo. Por supuesto, entendí cómo funcionan los compiladores y todo eso, pero no entendí la complejidad de los requisitos. Compromisos complejos para tratar, por ejemplo, en el campo de la gestión de la memoria. Es muy difícil elegir lo que al mismo tiempo dará mayor productividad al desarrollador de la aplicación y será efectivo. Este problema aún no se resuelve hasta el final. Rust o .NET nunca resolverán esto. El óxido es hermoso, sorprendente, pero es difícil trabajar con él, especialmente si está cambiando a algo como JavaScript. Sin embargo, hay ejemplos de desarrolladores de Python o JavaScript que están migrando a Rust, aunque esto es algo sorprendente.

R .: Usted mencionó que programó en C # durante los últimos 10 años. Entonces, ¿qué tiene de bueno C #? ¿Por qué no C ++, por ejemplo? C ++ parece ser un lenguaje más sistémico.

Para ser sincero, odio C ++, odio C, pero trabajo con ellos. Sinceramente, creo que conducen a un montón de errores, a una enorme ineficiencia en el desarrollo. Muchas personas piensan que, dado que está programando en C, ya está escribiendo de facto código rápido de que su programa estará orientado al rendimiento. Esto no es verdad Si esculpe montones de malloc y todo eso, será lento incluso en comparación con lo que está escrito en .NET. Los buenos desarrolladores de C / C ++ se ven obligados a usar trucos como el asignador de memoria regional . Tienes que enterrarte en un montón de cosas extrañas de las que nadie ha oído hablar. Aunque aquí los desarrolladores de juegos generalmente saben de esas cosas. Como mínimo, los desarrolladores de AAA o las personas que hacen juegos en marcos C / C ++. Algunos de los problemas provienen de la complejidad del lenguaje en sí. Antes, no leía libros en C ++, y hace solo tres o cuatro años comencé a leer libros solo en C ++, solo para sentir el lenguaje. Lo programé, pero no tenía un enfoque formal y sistemático, y me sorprendió su complejidad, la cantidad de cosas que puede arruinar si no escribe todo correctamente.

Hace tan solo un par de meses hubo un error en Unity, alguien cometió un error en un fragmento de código C ++, estaba en el constructor, algo pasó por valor y, como resultado, tomamos la dirección de este valor y buscamos en el caché. De hecho, nos referimos a un valor que ya no estaba en la memoria. Y todo esto porque los punteros estaban mezclados con no indicadores, y el que realizó esta refactorización no verificó todos los lugares de uso. Un código completamente diferente que funcionó perfectamente de repente dejó de funcionar. Parece ser un pequeño error, pero lo rompió todo. De hecho, esto es un error al trabajar con la memoria. Entonces, sí, cuando veo esas cosas, estoy convencido de que debemos restringir el acceso al trabajo en C y C ++, y minimizar su uso. En la parte .NET, realmente limité su uso solo a cosas específicas de la plataforma. Pero escribir todo en C # es bastante triste. Para acceder a la API, debe hacer un montón de dlopen. Aunque, por ejemplo, puede intentar encapsular todo esto en un contenedor en C y organizar el acceso a través de una sola función. Preferiría aislar tales cosas y desarrollarlas más en C y C ++. Pero este es un tema tan limitado sobre interoperabilidad, y luego te quedas con un lenguaje controlado normal, lo usas la mayor parte del tiempo y disfrutas de una compilación más rápida.

Odio los errores del compilador y el enlazador de C ++, odio la necesidad de trabajar con diferentes plataformas, todo esto es muy, muy difícil. Comienza a compilar en MSVC, luego debe cambiar a Clang, luego a GCC. En Linux, en Mac, en Windows, en Android, en iOS y así sucesivamente. ¡Trabajar con C ++ es una pesadilla!

Odio la separación entre archivos en el editor, archivos .h y archivos cpp. Las personas están completamente confundidas en el lenguaje y comienzan a programar en macros. Me encanta la metaprogramación, pero en C ++ moderno podemos hacer una locura completa. Por sí mismas, estas cosas son increíbles, pero en realidad ya es demasiado.

Para resumir: sí, creo que podemos desarrollar software efectivo en C #. Quizás no sea tan rápido como en C ++, pero podemos hacerlo. Esto es exactamente lo que estamos tratando de hacer en Unity, por ejemplo, estamos haciendo un compilador de ráfaga para compilar un subconjunto particular de C #, logrando el máximo rendimiento, incluso más en lugares de lo que hubiera sucedido en C ++, pero permaneciendo en C #. Es completamente seguro Para los punteros, debe declarar inseguro, no lanzar excepciones, hacer todo explícitamente. Y esta es una experiencia amarga. Pero aún así puede escribir código que será tan rápido como en C ++. Creo que esta es exactamente la dirección en la que vale la pena ir .NET y hacia dónde deberíamos ir.

R: Si hablamos de código fuente abierto, por ejemplo, tenemos un recolector de basura en .NET Core, que es un archivo C muy grande y aterrador. Dos megabytes de basura, muy probablemente generados por algún tipo de ceceo (apenas valía la pena escribir tantas cartas manualmente). ¿Quizás tiene sentido reescribir todo aquí en C #?

Si! Charlo con personas que trabajan en JIT tanto en Microsoft como en la comunidad. Hay algo en lo que realmente creo. Creo que hay un momento en que su lenguaje se vuelve más maduro y fundamental, y luego tiene que desafiar, probarlo para determinar su fuerza. Necesita poder usarlo como base. Demuestre que incluso puede usarlo para crear algo muy exigente en rendimiento. Y esta es la historia de Garbage Collector y JIT. Un porcentaje muy, muy grande de subsistemas de tiempo de ejecución .NET, incluidos JIT y GC, se puede hacer en C #. Si establece una regla que en C ++ solo puede describir abstracciones de la plataforma base, esto hará que la mayor parte de la plataforma en tiempo de ejecución sea independiente. Estaría muy feliz si esto sucediera. Pero este es un trabajo enorme.

Hay una razón por la que me gusta especialmente esta idea.Ya hablé sobre esto, refactorizar y mejorar la base de código en C / C ++ es tan complicado que en algún momento dejas de hacer esta refactorización. Duele tanto que ya no lo tocarás más. Tendrá que transferir y cambiar algunos archivos a mano, porque la refactorización en el IDE funcionará mal, por ejemplo, porque hay demasiadas plantillas, y así sucesivamente. Al desarrollar en C #, podría ser más ambicioso acerca de sus deseos. Agregar nuevas optimizaciones sería posible mucho más rápido y más fácil, simplemente porque el tiempo de compilación ha disminuido. Tiempo de iteración reducido para pruebas, etc. Es bueno que, por ejemplo, en CoreRT intenten usar C # tanto como sea posible en lugar de C ++. La situación está cambiando.

, .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» « ». , — . , , , . , , - — , . « , - ?»

, , . . , , . , - . , , , . — , , ? , ? , .

, . . ? ? , , . , … - , . . , , , .

. . ! , . — . , — - . , , , . , , , . , . , . . , - : « !». -, , , . , . .

, , , , , , , - , .



El próximo viernes, Alexandra hará una presentación "Detrás del compilador de ráfagas, convirtiendo .NET IL a código nativo altamente optimizado utilizando LLVM" en DotNext 2018 Moscú . La conferencia se llevará a cabo del 22 al 23 de noviembre en Moscú y, al parecer, será el DotNext más grande de todos. Te diríamos qué más esperar de la conferencia, pero fue mejor para nosotros por su otro orador, Dylan Beatty, él grabó toda la canción:

Source: https://habr.com/ru/post/es429242/


All Articles