2011-12-28 27 views
16

Usando sistemas como Parallel Linq, es posible dividir la ejecución de funciones anónimas, consultas, etc. en múltiples núcleos e hilos en una sola máquina. Me gustaría la capacidad de extender esto para ejecutar en varias máquinas utilizando construcciones de lenguaje estándar como bucles (como Parallel.For()), tipos de valores como int s, struct s, etc., y mantener las modificaciones de la fuente de la aplicación al mínimo. Idealmente, esto me permitiría abrir un proyecto, agregar un atributo a un método y volver a compilar para obtener acceso a la funcionalidad mejorada.Implementando extensiones de lenguaje C#

Parece que que iba a necesitar algo en la línea de:

  1. La capacidad de capturar un bloque de código compilado (tales como lambda) y pasarlo a un proceso de trabajo que se ejecuta en otro nodo , junto con cualquier dato que se requiera, o

  2. Proporcione un preprocesador que capture el código en cuestión, compílelo en una especie de proyecto de plantilla que reemplazaría referencias variables, etc., con referencias a una clase que manejaría comunicación de red, almacenamiento en caché y acceso a cualquier otro activo requerido, y envíe la DLL resultante a cualquier availa nodos de trabajadores que se ejecutan en otras máquinas.

Roslyn parece que proporciona algunas herramientas que serían útiles aquí. ¿Hay alguna forma de engancharse en la tubería de compilación actual para permitir esto?

Editar

Vale, sé esto es posible, because these guys did it. La pregunta es, cómo?

+5

De acuerdo, cerradores - ¿Cómo es esto demasiado localizado? –

+2

Porque debe ser la única persona aquí que desee implementar extensiones de lenguaje C# para crear núcleos OpenCL. –

+1

De acuerdo, olvídate de la parte OpenCL. ¿Cómo iría a la fase de compilación para personalizar la generación de código para distribuir la ejecución a través de plataformas heterogéneas? Eso apenas parece más claro para mí. ¿Y desde cuándo cerramos las preguntas sobre aplicaciones específicas? –

Respuesta

10

No tiene que extender el idioma para hacer lo que Brahma hace. Acaba de implementar un proveedor de consultas personalizado que analiza árboles de expresiones y emite código GPGPU (LINQ to SQL hace lo mismo pero con SQL).

He vinculado una guía básica en MSDN here que puede ponerlo en funcionamiento implementando un proveedor IQueryable.

La parte más difícil será atravesar los árboles de expresión y generar código OpenCL. Una vez que puedas hacer eso, simplemente se lo pasarás a Cloo y deberías estar corriendo.

Editar

se conectó una herramienta que compila el código .NET estándar de código de la GPU con un atributo [Kernel]. Lo hacen haciendo que una herramienta de post-construcción busque los atributos en la IL compilada y realicen la reescritura de IL para generar llamadas a la GPU. Esto es similar al PostSharp, una solución de AOP.

La reescritura de IL lleva mucho tiempo y es un trabajo duro, pero también puede seguir esta ruta.

+0

Impresionante; Gracias por la respuesta. Sigo teniendo curiosidad acerca de cómo implementar esto sin tener que usar un proveedor personalizado, como capturar bucles, etc. y reemplazarlos con referencias a dicho proveedor, pero esto resolverá el problema. –

+1

+1. Hay algunas bibliotecas que pretenden facilitar la implementación de un proveedor de LINQ personalizado, como [re-linq] (http://relinq.codeplex.com/). – TrueWill

+1

Los árboles de expresiones pueden representar bucles y la mayoría de las construcciones de sentencias a partir de C# 4. Si no desea la sintaxis del estilo LINQ, simplemente analice los árboles de expresiones usted mismo. Recuerde que puede asignar funciones lambda directamente a objetos de expresiones, por ejemplo: 'Expresión > someExpression = (i) => return" ¡Hola! "' –

11

Usando sistemas como Parallel Linq, es posible dividir la ejecución de funciones anónimas, consultas, etc. en múltiples núcleos e hilos en una sola máquina. Me gustaría la posibilidad de extender esto para ejecutar en múltiples máquinas utilizando construcciones de lenguaje estándar como por ejemplo para bucles (como Parallel.For()), tipos de valores como ints, structs, etc., y mantener las modificaciones de fuente de la aplicación a un mínimo .

Suena genial. De hecho, tenemos un sistema muy parecido en Microsoft Research, aunque obviamente no puedo discutir los detalles.

Necesito la capacidad de capturar un bloque compilado de código (tales como lambda) y pasarlo a un proceso de trabajo que se ejecuta en otro nodo, junto con los datos que se requiere

OK, tu lo tienes. Agregamos esa característica a C# 3. Así es como funciona LINQ to SQL. De alguna manera la consulta LINQ debe ingresar a la base de datos. La lambda compilada se interroga en la máquina del cliente, se transforma en una consulta que se envía al nodo del servidor y luego se devuelve el resultado.

Roslyn parece proporcionar algunas herramientas que serían útiles aquí. ¿Hay alguna forma de engancharse en la tubería de compilación actual para permitir esto?

Ese no es el propósito de Roslyn; Roslyn no se trata de agregar nuevas funciones al lenguaje C#. Se trata de facilitar el análisis del código para construir cosas como motores de refactorización.

No necesita engancharse en la tubería de compilación. PLINQ no cambia el compilador, LINQ to SQL no cambia el compilador, y así sucesivamente. Cuando convierte un lambda en un árbol de expresiones, el compilador emite un código que crea un árbol de expresiones en tiempo de ejecución que representa el lambda. Puede interrogar ese árbol de expresiones, serializarlo en otra máquina en su red, deserializarlo, convertirlo en un delegado y ejecutarlo si ese es el tipo de cosas que le gusta hacer.

Tendrá que escribir su propio serializador de árbol de expresiones y deserializador probablemente, pero son estructuras de datos bastante sencillas. Ser un árbol inmutable debería hacer que sean bastante fáciles de serializar y deserializar; en realidad no pueden formar redes complejas ya que siempre se construyen a partir de nodos hoja.

+0

Gracias, Eric. No había considerado la similitud con LINQ to SQL. Empecé a jugar con árboles de expresión esta mañana y trato de no cacarear demasiado fuerte. :) –

+0

Seguimiento: esto funciona increíblemente bien. Felicitaciones a MS por proporcionar un sistema tan flexible y extensible. Proporcionar validación en tiempo de compilación de código como datos es increíblemente genial. –