Pregunta

Estoy escribiendo mi propio lenguaje de scripting en C #, con algunas funciones que me gustan, y elegí usar MSIL como código de byte de salida (Reflection.Emit es bastante útil, y no tengo que inventar otro bytecode). Funciona, emite un archivo ejecutable, que puede ejecutarse (incluso descompilarse con Reflector :)) y es bastante rápido.

Pero, quiero ejecutar múltiples 'procesos' en un proceso + un subproceso, y controlar su tiempo de CPU asignado manualmente (también implemento un IPC mucho más robusto que ofrece el marco .NET) ¿Hay alguna forma de desactivar por completo el JIT? y crear una máquina virtual propia, paso a paso instrucción después de la instrucción utilizando .NET framework (y controlar el uso de la memoria, etc.), sin necesidad de escribir nada por mi cuenta, o para lograr esto, ¿debo escribir todo el MSIL interprete?

EDIT 1): Sé que interpretar IL no es lo más rápido del universo :)

EDIT 2): Para aclarar, quiero que mi VM sea una especie de "sistema operativo"; obtiene un tiempo de CPU y lo divide entre procesos, controla la asignación de memoria para ellos, etc. No tiene que ser rápido, ni efectivo, sino solo una prueba de concepto para algunos de mis experimentos. No necesito implementarlo en el nivel de procesamiento de todas las instrucciones. Si esto debe ser realizado por .NET, no me importa, solo quiero decir: paso uno, instrucciones, y espera hasta que te diga que hagas lo siguiente.

EDIT 3): Me di cuenta, que ICorDebug tal vez pueda satisfacer mis necesidades, ahora mirando la implementación del tiempo de ejecución de Mono.

¿Fue útil?

Solución

Podría usar Mono : creo que permite una opción para interpretar el IL en lugar de JITting . El hecho de que sea de código abierto significa (sujeto a la licencia) que también debería poder modificarlo según sus necesidades.

Mono no tiene todas las funciones de .NET, es cierto, pero puede hacer todo lo que necesita.

Otros consejos

Tenga en cuenta que MSIL fue diseñado para ser analizado por un compilador JIT. No es muy adecuado para un intérprete. Un buen ejemplo es quizás la instrucción ADD. Se utiliza para agregar una amplia variedad de valores de tipo de valor: byte, short, int32, int64, ushort, uint32, uint64. Su compilador sabe qué tipo de adición se requiere, pero perderá esa información de tipo al generar la MSIL.

Ahora necesita volver a encontrarlo en tiempo de ejecución y eso requiere verificar los tipos de valores en la pila de evaluación. Muy lento.

Un IL de fácil interpretación ha dedicado instrucciones ADD como ADD8, ADD16, etc.

La implementación de Microsofts del Common Language Runtime tiene un solo sistema de ejecución, el JIT. Mono, por otro lado, viene con ambos, un JIT y un intérprete.

Sin embargo, no entiendo qué es exactamente lo que desea hacer usted mismo y qué le gustaría dejar a la implementación de Microsofts:

  

¿Hay alguna forma de desactivar por completo el JIT y crear una máquina virtual?

y

  

... ¿sin necesidad de escribir nada por mi cuenta, o para lograr esto debo escribir todo el MSIL interpretar?

es algo contradictorio.

Si crees que puedes escribir un mejor sistema de ejecución que JIT de microsofts, tendrás que escribirlo desde cero. Tenga en cuenta, sin embargo, que tanto los microsofts como los monos JIT son compiladores altamente optimizados. (tiroteo en el lenguaje de programación)

No es posible programar el tiempo de CPU para los procesos del sistema operativo exactamente desde el modo de usuario. Esa es la tarea de los sistemas operativos.

Algunas implementaciones de hilos verdes podrían ser una idea, pero ese es definitivamente un tema para el código no administrado. Si eso es lo que quiere, eche un vistazo a la API de alojamiento de CLR.

Yo sugeriría que intentes implementar tu lenguaje en CIL. Después de todo, se compila hasta x86 en bruto. Si no te importa la verificabilidad, puedes usar punteros cuando sea necesario.

Una cosa que podría considerar hacer es generar código en un estilo de máquina de estado. Déjame explicarte lo que quiero decir con esto.

Cuando se escriben métodos generadores en C # con rendimiento, el método se compila en una clase IEnumerator interna que implementa una máquina de estado. El código del método se compila en bloques lógicos que terminan con un retorno de rendimiento o una declaración de interrupción de rendimiento, y cada bloque corresponde a un estado numerado. Debido a que cada rendimiento de rendimiento debe proporcionar un valor, cada bloque finaliza almacenando un valor en un campo local. El objeto del enumerador, para generar su próximo valor, llama a un método que consiste en una instrucción de cambio gigante en el número de estado actual para ejecutar el bloque actual, luego avanza el estado y devuelve el valor del campo local.

Su lenguaje de scripting podría generar sus métodos en un estilo similar, donde un método corresponde a un objeto de máquina de estado, y la máquina virtual asigna tiempo avanzando la máquina de estado durante el tiempo asignado. Algunas partes difíciles de este método: implementar cosas como las llamadas a métodos y los bloques try / finally son más difíciles que generar una MSIL directa.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top