Programación de bajo nivel: ¿qué hay para mí? [cerrado]

32

Durante años he considerado profundizar en lo que considero idiomas de "bajo nivel". Para mí esto significa C y montaje. Sin embargo, todavía no tuve tiempo para esto, y NUNCA ha sido necesario.

Ahora, como no veo surgir ninguna necesidad, siento que debería programar algún momento en el que estudiaré el tema o abandonaré el plan para siempre.

Mi posición

Durante los últimos 4 años me he centrado en las "tecnologías web", que pueden cambiar, y soy un desarrollador de aplicaciones, que es poco probable que cambie.

En el desarrollo de aplicaciones, creo que la usabilidad es lo más importante. Usted escribe aplicaciones para ser "consumidas" por los usuarios. Cuanto más utilizables sean esas aplicaciones, más valor tendrá.

Para lograr una buena usabilidad, creo que las siguientes cosas son viables

  • Buen diseño : características bien pensadas accesibles a través de una interfaz de usuario bien pensada.
  • Corrección : el mejor diseño no vale nada, si no se implementa correctamente.
  • Flexibilidad : una aplicación A debe evolucionar constantemente, de modo que sus usuarios no necesiten cambiar a una aplicación B diferente, que tenga nuevas características, que A pueda implementar. Las aplicaciones que abordan el mismo problema no deberían diferir en características sino en filosofía.
  • Rendimiento : el rendimiento contribuye a una buena experiencia de usuario. Lo ideal es que una aplicación siempre responda y realice sus tareas razonablemente rápido (según su frecuencia). El valor de la optimización del rendimiento más allá del punto en que el usuario lo percibe es cuestionable.

Creo que la programación de bajo nivel no me va a ayudar con eso, excepto por el rendimiento. Pero escribir una aplicación completa en un lenguaje de bajo nivel en aras del rendimiento es una optimización prematura para mí.

Mi pregunta

¿Qué podría enseñarme la programación de bajo nivel, qué otros lenguajes no me enseñarían? ¿Me estoy perdiendo algo, o es solo una habilidad, que es de muy poca utilidad para el desarrollo de aplicaciones? Por favor, comprenda que no estoy cuestionando el valor de C y el ensamblaje. Es solo que en mi vida cotidiana, estoy bastante feliz de que todas las complejidades de ese mundo se abstraigan y gestionen para mí (principalmente por capas escritas en C / C ++ y ensambladas). Simplemente no veo ningún concepto, eso podría ser nuevo para mí, solo detalles con los que tendría que pensar. Entonces, ¿qué hay para mí?

Mi conclusión

Gracias a todos por sus respuestas. Debo decir que nadie realmente me sorprendió, pero al menos ahora estoy bastante seguro de que abandonaré esta área de interés hasta que surja la necesidad.
Según tengo entendido, escribir ensamblajes en estos días para los procesadores, ya que están en uso en las CPU actuales, no solo es innecesariamente complicado, sino que corre el riesgo de tener un rendimiento de tiempo de ejecución más pobre que una contraparte en C. La optimización manual es casi imposible debido a OOE, mientras que no obtienes todo tipo de optimizaciones que un compilador puede hacer automáticamente. Además, el código es portátil, ya que utiliza un pequeño subconjunto de comandos disponibles o está optimizado, pero probablemente solo funcione en una arquitectura.
Escribir C ya no es tan necesario, como lo era en el pasado. Si tuviera que escribir una aplicación en C, utilizaría bibliotecas y marcos probados y establecidos, lo que me permitiría implementar rutinas de copia de cadenas, algoritmos de clasificación y otro tipo de cosas que sirven como ejercicio en la universidad. Mi propio código se ejecutaría más rápido a costa de la seguridad de tipo. No estoy interesado en volver a inventar la rueda en el curso del desarrollo normal de aplicaciones, ni en tratar de depurar mirando los volcados del núcleo: D
Actualmente estoy experimentando con idiomas e intérpretes, así que si hay algo que me gustaría publicar, supongo que Transmitiría un concepto de trabajo a C, aunque C ++ también podría funcionar.
Nuevamente, gracias a todos por sus respuestas y su visión.

back2dos
fuente
66
@TheLQ: mi pregunta no es por qué usarlo , sino qué puedo aprender de él .
back2dos
1
Ejemplo: Volver a lo básico .
rwong

Respuestas:

9

La programación de bajo nivel es para los casos de esquina donde existe un requisito que no está presente de inmediato en las computadoras de escritorio normales. Esto podría ser un cuello de botella de velocidad, o un cuello de botella de memoria o algo completamente diferente, y con mucha frecuencia es muy interesante ver qué se puede hacer con esos requisitos.

Piense en ello como Haikus o Limericks, donde las restricciones lo hacen interesante.

Para darle una idea de lo que es posible en lo que parecería imposible hoy, aquí está uno de los mejores hacks de la historia. ¡Ajedrez en 1 Kb de RAM! http://users.ox.ac.uk/~uzdm0006/scans/1kchess/


fuente
1
Creo que realmente voy por "las restricciones lo hacen interesante". De todas las cosas mencionadas aquí, este es probablemente el mejor. De vuelta en la escuela, estuve programando juegos en mi calculadora con 32kB de memoria y una CPU de 8Mhz. Fue divertido, pero no aprendí mucho de lo que podría beneficiarme ahora.
back2dos
Downvoter, por favor mencione por qué?
29

Estaba pensando esto recientemente. Actualmente me considero un desarrollador de C #, lo cual está perfectamente bien para mi carrera.

Sin embargo, de vez en cuando me pierdo las cosas de nivel realmente bajo (esencialmente 'ensuciarme las manos' al hacer ensambladores o controladores de dispositivos en C). Solo extraño la programación. No espero que eso me ayude en mi carrera masivamente. Si lo tuyo son los controladores de dispositivos o los sistemas integrados, entonces podría ser de gran ayuda.

Cuanto más programo en los lenguajes abstractos, más extraño lo que me metió en las computadoras en primer lugar: hurgar en la computadora y ver qué se contrae. Assembler y C son muy adecuados para hurgar :)

Al usar los idiomas más antiguos, creo que estás obligado a hacer casi todo por ti mismo. En C # puedo hacer algo como myArray.SortBy(x=>x.Name). De ninguna manera podría hacer eso en C. Estoy aceptando que el idioma hará la mejor clasificación por mí. Si tuviera que hacerlo en C, podría volver a los días de mis módulos universitarios y revisar mis diferentes algoritmos de búsqueda y clasificación.

Por lo tanto, creo que los idiomas de nivel inferior lo ayudarían a revisar cualquiera de los bits olvidados que se han abstraído. Más un desafío personal que una carrera que progresa.

Jonathon
fuente
15
+1 por expresar el amor de hurgar en el hardware y ver qué se mueve - un verdadero geek
Gary Rowe
2
Puede escribir la función de clasificación usted mismo en C # si lo desea. También puede usar una función de biblioteca para ordenar en C si lo desea: gnu.org/s/libc/manual/html_node/Array-Sort-Function.html. Incluso diría que al usar idiomas más antiguos, tienes que hacer menos cosas tú mismo. Porque la mayoría de los problemas ya han sido resueltos. De todos modos, eso no evita que la gente vuelva a colocar la rueda:
back2dos
15

Mi sugerencia es jugar con C como curiosidad intelectual. No invierta mucho tiempo porque no vale la pena.

Metas sugeridas:

  • Actualice su memoria sobre las estructuras de datos y algoritmos básicos.
    • Es algo bueno saber, como álgebra y geometría.
    • Intenta hacer algunos ejercicios de libros de texto universitarios o programar rompecabezas en C.
  • Una mejor apreciación de la jerarquía de memoria (ancho de banda) , desde el caché de la CPU hasta la latencia de la red transoceánica. Esto ayudará a sus habilidades de desarrollo de aplicaciones en todos los niveles.
    • Lo que es más importante, es bueno aprender sobre escenarios en los que una pequeña reordenación discreta de código de alto nivel puede resultar en una mejora dramática de la velocidad .
      • A veces, la razón solo se puede entender en la implementación de bajo nivel en el contexto de la jerarquía de memoria.
      • No comprender la causa natural de esta posibilidad conduce a la ignorancia , el miedo y, finalmente, a la negación , pensando que es incorrecto que los desarrolladores de alto nivel aprovechen este tipo de optimización. En realidad no hay nada de malo en eso.
  • Apreciar la estética de los sistemas de software basados ​​en componentes , que permite que los componentes de bajo nivel desarrollados en C / C ++ / Assembly sean utilizados por sistemas de alto nivel.
    • La estética es exactamente la misma que la usabilidad del software:
      • Buen diseño (potente, fácil de usar, bien pensado)
      • Exactitud
      • Flexibilidad (extensiones y nuevos comportamientos a través de la composición de partes existentes, cada una con un propósito claramente definido)
      • Rendimiento (sin complicar la usabilidad)
    • Si bien es posible que no diseñe sus propios componentes de bajo nivel, su comprensión lo ayudará a evaluar y elegir buenos componentes para usar en sus proyectos de alto nivel.
  • Finalmente, aprecie que los componentes de bajo nivel son casi siempre más complicados en sus implementaciones , lejos de ser insondables con solo mirar la interfaz.
    • El nivel bajo siempre es complicado. Una buena biblioteca oculta la complejidad sin disminuir su poder.
    • Aprenda a leer las "notas técnicas" escritas por los desarrolladores de componentes, que son sugerencias para los usuarios de componentes de nivel superior sobre cómo hacer un mejor uso de los componentes.
rwong
fuente
8

si desea comprender cómo funciona la máquina , y no solo la máquina virtual de la que depende su lenguaje de alto nivel, entonces Assembly le enseñará esto

Si no tiene motivos para preocuparse, y la mayoría de los programadores realmente no lo hacen en estos días, no se preocupe por eso.

mejorará su base, pero probablemente no mejorará sus aplicaciones web

Steven A. Lowe
fuente
66
C funciona casi tan bien. La mayoría de los conceptos de C son fácilmente traducibles al lenguaje de máquina. Aprenda C y eche un vistazo rápido al ensamblador, y estará en buena forma.
David Thornley
Estaba a punto de publicar una respuesta similar. Yo diría que C también proporciona una apreciación de cómo funciona la máquina, especialmente cuando se trata de administrar la memoria. Además, muchos idiomas que resumen la complejidad de la máquina se escriben en C. Al menos, la persona comprendería realmente lo mimados que están :)
Tim Post
1
@Jorg: interesante. ¿y cuántas de estas CPU están en uso comercial activo, en comparación con, por ejemplo, Intel x86 o 6502s?
Steven A. Lowe
1
@ Jörg, ¿dónde encuentras estas CPU?
1
@Thor: la velocidad no es la cuestión aquí, la educación sí.
Steven A. Lowe
8

Cada lenguaje de programación cambia un poco acerca de cómo piensas acerca de la programación en general. Un ejemplo concreto que puedo darle es cuando comencé a aprender haskell y, de repente, los bits funcionales de javascript, ruby ​​y python tenían mucho más sentido. Nunca antes había usado foldl en ninguno de mis códigos, pero después de haskell casi lo veo en todas partes donde veo matrices. Por lo tanto, hay muchas posibilidades de que si aprende algo de C se volverá mucho más consciente de las características de rendimiento relativo de varias construcciones en su lenguaje favorito. Hace unos minutos estaba escuchando una charla sobre la escritura de JavaScript rápido y optimizado y el orador dijo: "Si es difícil de hacer en C, entonces será muy lento en JavaScript". Su intención es que javascript sea un lenguaje interpretado y el intérprete esté escrito en C o C ++.

davidk01
fuente
2
+1 para la noción de cómo cada idioma cambia tu forma de pensar.
Sean
7

Si no lo haces solo por diversión, porque a los geeks realmente les encanta tener control total sobre su hardware, al menos podrías tener una mejor idea de cuánto más rápido puede ser un programa cuando se escribe en C en lugar de, por ejemplo, Java. También puede aprender a apreciar realmente las características de los lenguajes de nivel superior, como la recolección de basura.

usuario281377
fuente
1
+1 para la diversión geek. Aunque debo decir que no soy muy geek. Y odio el hardware :)
back2dos
1
La diferencia de velocidad suele ser irrelevante. Esto es especialmente cierto para las aplicaciones web, donde el procesamiento del lado del servidor generalmente no es el cuello de botella.
David Thornley
David: Estoy completamente de acuerdo con las aplicaciones web promedio de pan y mantequilla. En otros dominios, la diferencia puede ser muy relevante.
usuario281377
1
@ back2dos, si la idea de programar cerca del hardware no te atrae, entonces diría que no te molestes. Sería como forzarte a aprender latín solo porque fue la base de muchas lenguas románicas posteriores.
tcrosley
2
con suficiente memoria Java es tan rápido o más rápido que C.
5

¡Hurra por la curiosidad!

Es muy bueno tener una idea de lo que realmente está sucediendo en los niveles más bajos de un sistema complejo, incluso si no hay una necesidad lógica de saber para los deberes cotidianos. Con mucho, la mejor manera de asimilar las cosas a nivel de bits es construir su propia CPU. Debe pensar en códigos de operación de nivel de lenguaje de máquina, comprender por qué los conjuntos de instrucciones ortogonales son tan buenos, las complicaciones del manejo de interrupciones, las compensaciones entre circuitos complejos frente a microcódigos (por ejemplo, en unidades de multiplicación) y ¡tanta diversión!

Pero eso, obviamente, requiere conocimientos de electrónica y lleva mucho tiempo, por lo que lo mejor es jugar con una CPU de 8 bits de estilo antiguo. Los microcontroladores como el 8051 todavía se usan ampliamente y están disponibles para los aficionados. Eso todavía requiere algo de conocimiento en electrónica de pastoreo y hacer que los LED brillen sin fumar, y cuesta $$ si aún no está equipado para la electrónica.

Lo mejor después de eso: jugar en un simulador de CPU (¿emulador? Tengo esos términos mezclados): existen para Z80, 6502, 8086 ... todos los viejos 8-bitters. Eso puede ser lo más educativo y divertido para un programador de aplicaciones que no sabe qué extremo del soldador debe sostener (aunque uno aprende eso bastante rápido :) Cómo se escribe el texto en la memoria de video, cómo los trucos del código de ensamblaje ayudan con el rendimiento. ... hay muchas cosas divertidas para explorar a este nivel.

No estoy tan seguro de aprender C como un lenguaje más, sin una comprensión inicial del funcionamiento interno de la CPU. Saber cómo se envían los bits entre los registros de la CPU y cómo se accede a la memoria, ayuda enormemente a obtener realmente punteros y otros conceptos de lenguaje C.

DarenW
fuente
+1 porque esta fue la única respuesta que mencionó punteros. Pensé que sería el número 1 y acepté la respuesta.
Erik
4

En una palabra, diversión. Cuando solía jugar con el ensamblador (después de trabajar de VB a C ++, C, etc.) fue increíble mover datos de una parte del procesador a otra. Fue una gran sensación saber exactamente lo que estaba sucediendo dentro de la CPU, sin preocuparse por lo que estaba sucediendo debajo de lo que no sabías. Además de una gran sensación de libertad: puede hacer casi cualquier cosa, porque no hay limitaciones incorporadas que encuentre en los idiomas de nivel superior.

Además, poder recurrir a cualquiera que haya programado en cualquier otro idioma y decir 'bueno, si no eres lo suficientemente duro ...' fue una diversión infantil, infantil.

Dan O
fuente
44
En realidad, están sucediendo muchas cosas dentro de la CPU que no se ven desde el ensamblador. La CPU está haciendo cosas automáticamente como ejecución fuera de orden, hyperthreading y almacenamiento en memoria caché. Siempre puedes ir un paso más abajo, hasta llegar a las partículas fundamentales de la materia. ¿O es la materia solo energía?
Kevin Panko
Uno puede evitar cualquier misterio oculto construyendo su propia CPU a partir de transistores y chips lógicos: D (¡Una de mis fantasías tecnológicas favoritas!) De todos modos +1 para una gran respuesta.
DarenW
¡Punto justo! Aunque la última vez que usé el ensamblador, hyperthreading probablemente se tomó más comúnmente como una referencia a la costura rápida, en lugar de CPU ...
Dan O
2

¿Hay alguna buena razón para aprender / practicar programación de bajo nivel? Tengo varias respuestas según el contexto.

Primero, estoy enseñando programación C (pero también OCaml y Java), motivar a los estudiantes a aprender programación desde el lado difícil es probablemente la parte más difícil de la tarea. El mejor argumento que he encontrado hasta ahora es la "comprensión": los lenguajes de nivel superior ocultan muchos mecanismos subyacentes y algunas veces no son para bien, también lo empujan a permanecer en el nivel superior incluso cuando algunos trucos de bajo nivel realmente podrían ser útiles ( para el rendimiento, la mayoría de las veces.) Comprender lo que está usando realmente puede ayudarlo a usarlo mejor. Mi experiencia docente me demuestra que los estudiantes que han aprendido programación de nivel inferior (y otros compiladores no orientados al usuario) son más adaptables y aprenden nuevos conceptos o herramientas de nivel superior más rápidos.

En segundo lugar, como usted dice, el rendimiento es parte de la experiencia del usuario. La mayoría de las veces, el rendimiento se ve como una cuestión de escritura compleja y cercana al código de máquina. Este no es siempre el caso, el rendimiento es mucho más una cuestión de algoritmos y estructuras de datos, sino también la interacción entre algo y datos. Utilizo un proyecto especial sobre el tema, básicamente es una simple búsqueda de ruta, pero el problema real es el tamaño de los datos: el gráfico es infinito. La única forma de lograr rendimientos de descenso y encajar en la memoria es escribir un asignador de memoria dedicado (de hecho, dos, un asignador de grupo y un asignador de reciclaje). Esto es algo que no se puede hacer en la mayoría de los idiomas de nivel superior. De hecho, la mayoría de los idiomas recolectados de basura tendrán problemas de rendimiento y memoria.

Probablemente haya muchos más argumentos, como la estabilidad (en el sentido de la historia y la longevidad) de los lenguajes de nivel inferior frente a los "exagerados" (el hecho de que un lenguaje considerado como referencia futura para la programación pueda desaparecer en unos pocos años es muy largo). historia, uno no puede predecir la longevidad de un material nuevo, pero este argumento sigue siendo cierto para los idiomas más antiguos ...), por supuesto, también hay una cuestión de gustos, o el hecho de que lo que se puede hacer en la mayoría de los idiomas de alto nivel también puede ser hecho en idiomas de nivel inferior pero no al revés (pero teniendo en cuenta eso, todos deberíamos codificar solo en ensamblador ...)

Yo mismo estoy atrapado en ambos mundos (de manera bastante diferente), pasé varios años trabajando en el concepto de programación teórica, el diseño de sistemas de tipo y la prueba, y al hacerlo solo tengo que usar y estudiar lenguajes de muy alto nivel (principalmente uno funcional, pero también puro orientado a objetos.) Recientemente volví al otro lado (principalmente programación de sistema y kernel) y me encontré bastante a gusto en esta área. ¡Me estoy divirtiendo mucho! Para mí, el siguiente paso es encontrar el punto común: ¡características de lenguaje de nivel superior para programación de nivel inferior! Entonces, hasta ahora no hay un lenguaje para eso (tal vez Google busque la programación del sistema de usuario) y estoy considerando la idea de construir mi propio idioma, pero esta es otra historia.

Marwan Burelle
fuente
1

Diría que no hay muchas razones en su dominio, sin embargo, si tuviera que hacer algo de computación de alto rendimiento (por ejemplo, juegos, ciencia, etc.) estaría justificado.

Noche oscura
fuente
1
No estoy tan seguro de que queden muchas áreas de alto rendimiento. Los juegos ciertamente no requieren idiomas de bajo nivel. Para los juegos, usualmente usas motores o al menos comienzas con OpenGL o algo así. Y para la ciencia, la paralelización es muy importante y la corrección. Supongo que estarías mejor con OCaml o algo así. Las áreas críticas de rendimiento ya no son aquellas que reducen muchos números, sino que se usan con mucha frecuencia, como núcleos, controladores, motores de almacenamiento y demás. Supongo que menos del 1% de todos los desarrolladores realmente los tocan.
back2dos
44
@ back2dos, los motores de juego no aparecen de la nada: alguien tiene que escribirlos. ¿Y en qué crees que está escrito OpenGL? No c#. Uno no necesita usar lenguajes de bajo nivel para la mayoría de las aplicaciones en estos días ... pero mucha gente trabaja en las otras áreas que lo requieren.
GrandmasterB
1

Creo que hoy en día la programación de bajo y alto nivel puede estar bastante separada. Básicamente, esto significa que podría vivir toda su vida profesional sin conocer C y ensamblador sin ningún problema. Dicho esto, el lenguaje de programación C no puede enseñarle mucho desde los puntos de vista de programación y diseño.

Solo por curiosidad podrías aprender cómo funcionan las cosas en un nivel inferior. Cuando estaba en la universidad, por ejemplo, disfruté usando gcc para generar código ensamblador desde C ++. Fue útil comprender cómo se implementan el polimorfismo y la excepción. Pero aparte de eso, las únicas cosas que puedes aprender de C hoy en día son:

1) trucos de memoria sucia. C es la mejor manera de entender que no hay fondo en la locura de los programadores :)

2) Los GOTO se usan realmente (y son útiles) para deshacer errores

3) aprender mejor cómo funciona la asignación de memoria (¿diferencia entre apilar y apilar a alguien?).

Básicamente, mi tesis es: si ya terminaste la Universidad y todavía no necesitas C, entonces no lo aprendas :)

Emiliano
fuente
2
Saber C para saber cómo funcionan las cosas a un nivel bajo puede ayudar a comprender por qué las cosas van mal cuando tienes una abstracción permeable.
Michael Shaw
1

No es necesario que comprenda los idiomas de bajo nivel, pero debe comprender lo que sucede debajo de las cubiertas del idioma de alto nivel elegido. Usar un lenguaje de bajo nivel te enseñará esto, pero no es la única forma.

Aquí hay algunos ejemplos de conceptos de bajo nivel que pueden afectar los lenguajes de alto nivel.

Punteros:

List<object> listOne = new List<object>();
List<object> listTwo = listOne;

listTwo.Add(new object());

Debug.WriteLine(listOne.Count); //do you know what this will be?

Instrumentos de cuerda:

string initial = "initial";
string another = initial;

another = "changed!";
Debug.WriteLine(initial); //what about this?

Liza:

¿Cuándo utiliza una lista frente a una lista vinculada? (Casi imposible saber esto sin comprender a un nivel bastante bajo de cómo funciona una lista)

-

¿Es necesario saber todo esto? No, pero puede tener un impacto y si quieres ser un maestro de un lenguaje de alto nivel necesitas tener una idea bastante buena del funcionamiento interno.

Alistair
fuente
1

¿Qué podría enseñarme la programación de bajo nivel, qué otros lenguajes no me enseñarían?

En particular, le enseñará cómo funcionan realmente las computadoras. No hay otra forma de aprender esto que a través de la programación de bajo nivel. No importa qué tipo de aplicaciones programe, esto siempre será útil. De hecho, comprenderá lo que sucede en el fondo debajo de todas esas cosas web. Y si está trabajando con Windows, toda la API está escrita en C, por lo que saber ese lenguaje le permitirá comunicarse directamente con el sistema operativo, siempre que necesite utilizar una función que carece de sus idiomas actuales y sus bibliotecas.

Por supuesto, la programación de bajo nivel le permitirá trabajar con cosas completamente diferentes, como la programación integrada y la programación en tiempo real, donde asm / C / C ++ es imprescindible. Si no tiene interés en este tipo de aplicaciones, no hay mucha necesidad de aprender asm / C / C ++.

Además, aprenderá bits y bytes. Manipulaciones de bits, hexadecimales, etc. Estas cosas que puede encontrar de vez en cuando incluso al hacer programación web / de escritorio. Los algoritmos de cifrado son uno de esos ejemplos en los que se usa.


fuente