¿Lenguaje de programación donde cada llamada / bloque de función se realiza en un hilo separado? [cerrado]

26

Actualmente estoy creando un lenguaje de programación por diversión, donde la idea es que cada llamada de función / bloque nuevo (si las cláusulas, bucles, etc.) funcionarán en un hilo separado. En lugar de crear nuevos subprocesos, el estándar debería ser que lo haga automáticamente, y si desea que se ejecute en el subproceso principal, deberá especificarlo.

No estoy tan informado sobre la programación paralela de subprocesos múltiples, pero sí sé lo básico (Futuros, objetos seguros para subprocesos). Por lo tanto, me pregunto cómo podría ser un lenguaje semejante en cuanto a sintaxis y si es posible comenzar. El objetivo no es hacerlo "útil", es más por diversión y por una experiencia de aprendizaje.

(Lo siento si este es el lugar equivocado para publicar. De ser así, agradecería que me señalaras el lugar correcto donde se permite una pregunta como la mía).

Grimbox
fuente
17
Crear hilos es simple. El truco con los subprocesos múltiples es cuando necesitan hablar entre ellos o trabajar con los mismos recursos. En otras palabras, no es la bifurcación lo que es difícil, son las uniones. El principal problema que debes resolver es cómo controlas eso.
JimmyJames
20
En mi opinión, no puede hacer eso sin estirar seriamente la definición habitual de la palabra "función" o la palabra "hilo". Es posible que desee leer sobre actores si aún no está familiarizado con ellos: en.wikipedia.org/wiki/Actor_model
Solomon Slow
99
Aprenda lo suficiente, y encontrará que las CPU ya paralelan las instrucciones automáticamente, sin poner ninguna carga adicional en el desarrollador de software. Consulte Ejecución fuera de orden y Procesador superescalar .
8bittree
8
Eso en realidad suena un poco horrible. Iba a explicar por qué, pero Karl Bielefeldt ya lo hizo.
Mason Wheeler
1
¿Qué tipo de paradigma quieres apoyar en tu idioma? ¿Debería ser imperativo o funcional? ¿Está diciendo que todas las declaraciones se ejecutarían al mismo tiempo, los bloques then / else junto con lo que viene después?
Bergi

Respuestas:

39

cada llamada a función / bloque nuevo (si cláusulas, bucles, etc.) funcionará en un hilo separado.

Lea mucho más sobre las continuaciones y el estilo de paso de continuación (y su relación con hilos o corutinas). Sugiero leer SICP y Lisp en piezas pequeñas . Además, Programming Language Pragmatics ofrece una visión general útil de varios lenguajes y le ayudará a diseñar el suyo propio.

Por lo tanto, me pregunto cómo podría verse un lenguaje así en cuanto a sintaxis

La sintaxis no importa mucho para explorar ideas . La semántica importa mucho más. Sugiero adoptar una sintaxis similar a S-expr (para que pueda crear prototipos con Scheme y su llamada / cc ) al principio.

Una vez que sus ideas sean más claras (después de un poco de experimentación), podría discutirlas en lambda-the-ultimate , podría definir una sintaxis más sexy (que realmente importa si desea que las personas adopten su idioma, y ​​lo que también importa es la calidad de implementación, una implementación de muestra de software libre, la documentación, la biblioteca estándar, la interfaz de funciones externas, etc.

Basile Starynkevitch
fuente
25
+1 por la mención de por qué la sintaxis es irrelevante. Otro +1 si pudiera para explicar por qué la sintaxis es tan importante.
Jörg W Mittag
Buena sugerencia, pero para hablar sobre cosas en LtU querrías una cuenta y no es trivial obtener una de mi experiencia.
Mael
1
Debe usar un grupo de subprocesos para reducir la sobrecarga. en.wikipedia.org/wiki/Thread_pool
shawnhcorey
37

Puede que le interese leer sobre la investigación en datos paralelos de Haskell . Si busca en YouTube, Simon Peyton Jones también ha dado algunas charlas interesantes relacionadas con el tema.

Si recuerdo correctamente de sus charlas, en programación puramente funcional, es casi trivial encontrar oportunidades para crear hilos. Su principal problema en su investigación es tener demasiados que son de corta duración, de modo que la sobrecarga de crear hilos y comunicar sus resultados esencialmente supera los beneficios del paralelismo. Por ejemplo, es fácil enseñarle a un compilador a girar 100 hilos para calcular sum $ fmap (+1) <100 length vector>, pero ¿valdrá la pena la sobrecarga?

El truco consiste en consolidar los hilos en tamaños beneficiosos, sin imponer una carga en el programador para denotarlo manualmente. Es un problema difícil que debe resolverse para utilizar de manera efectiva futuras PC con miles de núcleos.

Karl Bielefeldt
fuente
8
Ya estaría feliz de trabajar con una PC pasada de moda con solo cientos de núcleos ...
Hagen von Eitzen
8
Me gustaría señalar que, para diseños muy paralelos a los datos, ya hemos estado haciendo mucha paralelización de manera muy efectiva: las GPU son esencialmente máquinas de 200 a 1000 núcleos (incluso tienen su propia jerarquía de memoria).
Delioth
44
@HagenvonEitzen: El Azul Vega JCA (Java Compute Appliance) tenía 16 CPU con 54 núcleos cada una para un total de 864 núcleos, y no era una máquina de nivel de investigación o prototipo, sino un producto real. Tampoco llenaba todo un edificio o incluso una habitación completa, era un electrodoméstico del tamaño de un escritorio. Y estaba disponible hace 9 años. Las GPU ya se mencionaron, sin embargo, esta era una máquina con 864 núcleos de CPU de propósito general .
Jörg W Mittag
3
Por supuesto, hay una razón por la que hacemos tenemos hoy los datos masiva de GPU-paralelo, pero ya no los masiva multi-core CPU es para equipos de sobremesa. Los primeros son comercialmente viables, los segundos no lo son, y eso se debe a que no se pueden programar de manera eficiente.
MSalters
@MSalters ¿tal vez solo necesitamos un número infinito de monos? ¿O los programas Quantum que simplemente ejecutan todas las operaciones posibles en cada paso?
15

Esto es exactamente lo que hace Erlang. Se encarga de volver a unir los hilos principalmente mediante el uso de colas. Es un concepto brillante pero un poco difícil de entender inicialmente si su experiencia es más de lenguajes de tipo procesal. Recomiendo investigarlo.

GenericJam
fuente
4

En primer lugar, le recomendaría que consulte PROMELA , un lenguaje utilizado para describir un algoritmo concurrente, de modo que un verificador de modelos pueda aplicar la fuerza bruta a todas las ejecuciones posibles para verificar que sea incapaz de un comportamiento incorrecto. (La programación concurrente es notoriamente difícil de entender, por lo que tales técnicas de verificación son importantes). No ejecuta todas las construcciones en hilos separados, pero tiene una sintaxis y semántica bastante extraña porque su enfoque es el no determinismo de los programas concurrentes.

Yendo más abstracto, el cálculo π es un enfoque hermoso para modelar computación paralela. Es difícil entenderlo a menos que obtenga el libro Communicating and Mobile Systems: The Pi Calculus , de Robin Milner. Me ayudó a pensar en la computación paralela en un sentido más amplio que "múltiples hilos que acceden a una memoria compartida". Es bastante interesante cómo se pueden construir enunciados condicionales, "gotos", etc., a partir de primitivas más simples, naturalmente paralelas.

Con respecto a la sintaxis ... la mejor manera de resolver esto es escribir algunos programas de muestra. Escriba un programa para ordenar una matriz, o haga ping simultáneamente a varios servidores e informe cuál responde más rápido, o intente resolver un laberinto en paralelo, o lo que sea. Mientras hace esto, las cosas que faltan en su sintaxis se harán evidentes y puede agregarlas. Después de haber agregado varias cosas, pregúntese si tienen algo en común y, de ser así, tal vez pueda encontrar un enfoque más simple que pueda tener múltiples propósitos.

Artelius
fuente
4

Proyectos similares se han intentado en el pasado. Sugiero leer sobre los clásicos para saquear ideas. (Todos los enlaces van a Wikipedia)

  • Unidad Este lenguaje fue / es usado para enseñar programación paralela. No creo que se haya implementado realmente. La sintaxis es algo críptica, pero básicamente tiene una colección de declaraciones que se ejecutan en un orden desconocido y repetidamente hasta que no hay nada más que hacer. Esto es lo más cercano a lo que pides.

  • Occam Este lenguaje fue diseñado para usarlo realmente, pero nunca lo entendió. Aquí hay una palabra clave PAR que significa que una lista de declaraciones debe ejecutarse en paralelo.

  • Erlang Otro idioma del mundo real. Este es utilizado por la compañía de telecomunicaciones Ericsson y tiene muchos seguidores. Han trabajado mucho para hacer que el paralelismo sea práctico y utilizable.

  • Google GO Este es mi favorito del grupo. Conceptualmente es lo mismo que Erlang, pero con una mejor sintaxis y el peso de Google detrás. ¿Qué podría salir mal?

Me gustaría cerrar con una advertencia: el paralelismo es muy difícil de acertar. La mayoría de los errores en los programas modernos son el resultado de equivocarse . ¿Estás seguro de que quieres ir allí?

Stig Hemmer
fuente
Sin ofender a ningún idioma que no esté en mi lista Es solo que mi conocimiento es limitado.
Stig Hemmer
3

Es posible, pero no sería útil para más del 99% de todas las aplicaciones pensables. La lógica está típicamente unida a la secuencia, es un flujo. Paso a paso, llega a una solución a un problema y el orden de los pasos es importante, principalmente porque la salida de un paso se ingresará para el siguiente.

En los pocos casos que tiene muchas tareas que se pueden realizar independientemente una de la otra, generalmente es barato configurarlas secuencialmente antes de permitir que se ejecuten en paralelo.

Por lo tanto, creo que sería mejor dedicar su tiempo a aprender cómo usar las funciones de subprocesos múltiples en su lenguaje de programación favorito.

Martin Maat
fuente
55
Esta es una excelente respuesta a una pregunta diferente; OP no pregunta acerca de la sabiduría de tal esquema, sino simplemente si se puede hacer y cómo sería la "sintaxis".
DepressedDaniel
99
Los que no lo piden son los que más necesitan mi sabiduría. Si alguien pregunta si es posible descender una colina en un carrito de compras, la mejor respuesta no sería "¡Apuesta! ¡Asegúrate de engrasar las ruedas!". Sería más como "Bueno, sí, pero ...".
Martin Maat
Me recuerda a la antigua instrucción de lenguaje ensamblador EIAO: Ejecutar en cualquier orden . (¿Y dónde está esa clave de todos modos?)
@MartinMaat nadie se va a suicidar escribiendo un lenguaje de programación por diversión
user253751
2

Clojure puede valer la pena ver algunas ideas.

http://clojure-doc.org/articles/language/concurrency_and_parallelism.html

Aquí hay algunos pensamientos: si llamamos a una unidad de cómputo que se puede realizar de forma independiente una tarea: 1. Las tareas son independientes, por lo que se pueden ejecutar de forma simultánea 2. Las diferentes tareas requieren diferentes recursos y requieren diferentes tiempos para ejecutarse 3. Por lo tanto, las tareas deben programarse para un rendimiento máximo 4. El único programa en condiciones de actuar como planificador es el sistema operativo

Cosas como el despacho central de las manzanas son un intento de proporcionar un planificador de este tipo.

Lo anterior significa que la responsabilidad de ejecutar tareas no es necesariamente la del lenguaje de programación.

Una segunda idea es reducir la carga de programar sistemas paralelos tanto como sea posible. La única forma de hacerlo es eliminar cualquier especificación de cómo se debe hacer algo desde el programa. Un programa solo debe especificar lo que se debe hacer y el resto debe suceder automáticamente.

Lo anterior probablemente significa que los lenguajes dinámicos y la compilación justo a tiempo son el camino a seguir.

foobar
fuente
2

Lo que estás buscando se llama paralelismo implícito, y hay lenguajes que han explorado este concepto, como Sun / Oracle's Fortress . Entre otras cosas, (potencialmente) ejecuta bucles en paralelo.

Desafortunadamente, se ha descontinuado y hay muchos enlaces muertos por ahí, pero aún puede encontrar algunos archivos PDF flotando por ahí, si googlea lo suficiente:

https://www.eecis.udel.edu/~cavazos/cisc879-spring2008/papers/fortress.pdf (la especificación del idioma)

http://stephane.ducasse.free.fr/Teaching/CoursAnnecy/0506-Master/ForPresentations/Fortress-PLDITutorialSlides9Jun2006.pdf

http://www.oracle.com/technetwork/systems/ts-5206-159453.pdf

http://dl.acm.org/citation.cfm?id=1122972 (pagado)

Vale la pena señalar que, por lo general, no querría comenzar un hilo real para cada declaración / expresión, ya que crear e iniciar hilos tiende a ser costoso; en cambio, tendría un grupo de hilos en los que publicará fragmentos de trabajo que deben realizarse . Pero ese es un detalle de implementación.

gustafc
fuente
1
+1 por mantener la Fortaleza ... Me gustó mucho la idea del lenguaje. Estaba realmente triste cuando anunciaron que el desarrollo se interrumpió ...
Roland Tepp
2

Si bien no es un lenguaje de programación como tal, debería echar un vistazo a VHDL . Se utiliza para describir los circuitos digitales, que naturalmente hacen todo en paralelo a menos que usted le indique específicamente que lo haga en serie. Podría darle algunas ideas sobre cómo diseñar su lenguaje y para qué tipo de lógica podría ser adecuada.

OnePie
fuente
0

Esto se puede simular con bastante facilidad en C ++. Solo asegúrese de que "cada" función de llamada sea implementada por a std::future. El manejo del valor de retorno se realiza simplemente llamando .get()al futuro.

Por lo tanto, puede crear prototipos de su lenguaje compilando en C ++. Esto también nos dice cómo se vería la sintaxis: la principal diferencia es que separa el punto de llamada (donde se proporcionan los argumentos de entrada) del punto de retorno (donde se usa la salida de la función).

(*) Digo "cada función", pero depende de usted lo que cuenta como una función. ¿Es memsetun intrínseco o una función? ¿La asignación de enteros o la asignación de tipos definidos por el usuario es una llamada de función?

MSalters
fuente
Y, si posterga la respuesta a una pregunta el tiempo suficiente, generalmente la necesidad de una respuesta desaparece. Creo que esto se llama "Lazy Existing".