¿Emular la caché de la CPU?
- jotego
- Atari 1040 STf
- Mensajes: 657
- Registrado: 16 Ene 2013, 23:25
- Sistema Favorito: Atari ST
- primer_sistema: Amstrad CPC
- consola_favorita: Sony PlayStation 2
- Primera consola: Atari Lynx
- Ubicación: Valencia (España)
- Gracias dadas: 27 veces
- Gracias recibidas: 44 veces
- Contactar:
¿Emular la caché de la CPU?
He encontrado una referencia a un emulador multisistema llamado Xe, que según el autor, está casi acabado. Me ha extrañado mucho que entre lo que le falta por acabar esté la caché de la CPU para nintendo 64 y PS1. Pero no entiendo bien por qué eso podría ser importante en un emulador. ¿Qué más da si la CPU tenía una caché o no? Lo que importa es ejecutar las instrucciones en orden, ¿o no? Esto en sistemas de 8 bits, donde las CPU no tenían caché, no es una preocupación y como todos los emuladores que hice son de 8 bits nunca me enfrenté con este problema. Aun así, no veo el porqué de emular la caché. ¿Alguna idea?
- zup
- Amiga 2500
- Mensajes: 3013
- Registrado: 04 Sep 2009, 20:07
- Sistema Favorito: Spectrum 16Kb/48Kb
- primer_sistema: Spectrum 16Kb/48Kb
- consola_favorita: Nintendo DS/3DS
- Primera consola: Nintendo GameBoy
- Ubicación: Navarra
- Gracias dadas: 86 veces
- Gracias recibidas: 359 veces
- Contactar:
Re: ¿Emular la caché de la CPU?
Bueno, tienes razón y estás muy equivocado.
La teoría dice que tú tienes razón, pero la caché cambia el comportamiento de algunas cosas. Si mal no recuerdo, muchos micros implementan pipelines. Desde el momento en que una instrucción entra en el pipeline del micro, ya no puede ser alterada; este método creo que se utilizaba para diferenciar micros 80x86 entre ellos (y detectar depuradores). Supongamos que yo tengo esta secuencia (ensamblador de Z80, que creo que NO tiene pipelines ni precarga de instrucciones).
La teoría dice que ese ret nunca se ejecutará (se ejecutaría el opcodenuevo), pero si el micro ha metido la instrucción en el pipeline o en una hipotética precarga (¿se denominaba prefetch? maldita memoria) esa instrucción cambiará en la RAM pero no en el micro. Por tanto, se ejecutaría el ret. En el caso de escribieras ese trozo de código (automodificable) y estuviera metido en una caché, el ret no se ejecutaría ya que al escribir sobre ella, la caché se considera inválida o se reescribe.
Otro caso es si quieres emular cosas "cycle-accurate". Si un elemento se tiene que pillar de la RAM, tarda x ciclos en aparecer por el bus; si lo tiene que pillar de la caché de la RAM serán y y si está en la caché del micro serán z (presumiblemente z<y<x). Emulando un PC no importa demasiado (demasiadas configuraciones diferentes), pero si quieres emular un sistema "cerrado" (sin diferentes configuraciones) quizás quieras intentar emularlo de la manera más "real" posible. La presencia de la caché hara que haya diferencias de temporizaciones (que luego pueden ser importantes o no).
También (en tiempos de los 486), sabiendo la longitud de cada línea de caché, había programadores que escribían sus programas para que un bucle cupiera en una línea de caché... así conseguían "gratis" ventajas de velocidad.
Otros temas que pueden estar relacionados es que no siempre los datos de la caché bajan a RAM/disco, ni se refrescan automáticamente (aunque esto último es más raro). Puede que en un momento dado (la teoría vuelve a decir que no debería suceder), haya diferencias entre los datos de la RAM y los de la caché. En estos casos sí es muy importante tenerlos correctamente emulados.
Como última cuestión, no sé cómo lo tendrán los emuladores más avanzados, pero desde que existen los pipelines las instrucciones no son atómicas: en un momento dado tu micro está ejecutando la decodificación de una instrucción, ejecutando otra y escribiendo los resultados de una tercera (como poco, habitualmente hay más fases en un pipeline). Otra cuestión interesante es que hay micros que pueden ejecutar instrucciones fuera de orden, con lo que ya te da por meterte a un manicomio porque te rompen todos los esquemas.
La teoría dice que tú tienes razón, pero la caché cambia el comportamiento de algunas cosas. Si mal no recuerdo, muchos micros implementan pipelines. Desde el momento en que una instrucción entra en el pipeline del micro, ya no puede ser alterada; este método creo que se utilizaba para diferenciar micros 80x86 entre ellos (y detectar depuradores). Supongamos que yo tengo esta secuencia (ensamblador de Z80, que creo que NO tiene pipelines ni precarga de instrucciones).
Código: Seleccionar todo
ld hl, etiqueta
ld (hl), opcodenuevo
:etiqueta
ret
La teoría dice que ese ret nunca se ejecutará (se ejecutaría el opcodenuevo), pero si el micro ha metido la instrucción en el pipeline o en una hipotética precarga (¿se denominaba prefetch? maldita memoria) esa instrucción cambiará en la RAM pero no en el micro. Por tanto, se ejecutaría el ret. En el caso de escribieras ese trozo de código (automodificable) y estuviera metido en una caché, el ret no se ejecutaría ya que al escribir sobre ella, la caché se considera inválida o se reescribe.
Otro caso es si quieres emular cosas "cycle-accurate". Si un elemento se tiene que pillar de la RAM, tarda x ciclos en aparecer por el bus; si lo tiene que pillar de la caché de la RAM serán y y si está en la caché del micro serán z (presumiblemente z<y<x). Emulando un PC no importa demasiado (demasiadas configuraciones diferentes), pero si quieres emular un sistema "cerrado" (sin diferentes configuraciones) quizás quieras intentar emularlo de la manera más "real" posible. La presencia de la caché hara que haya diferencias de temporizaciones (que luego pueden ser importantes o no).
También (en tiempos de los 486), sabiendo la longitud de cada línea de caché, había programadores que escribían sus programas para que un bucle cupiera en una línea de caché... así conseguían "gratis" ventajas de velocidad.
Otros temas que pueden estar relacionados es que no siempre los datos de la caché bajan a RAM/disco, ni se refrescan automáticamente (aunque esto último es más raro). Puede que en un momento dado (la teoría vuelve a decir que no debería suceder), haya diferencias entre los datos de la RAM y los de la caché. En estos casos sí es muy importante tenerlos correctamente emulados.
Como última cuestión, no sé cómo lo tendrán los emuladores más avanzados, pero desde que existen los pipelines las instrucciones no son atómicas: en un momento dado tu micro está ejecutando la decodificación de una instrucción, ejecutando otra y escribiendo los resultados de una tercera (como poco, habitualmente hay más fases en un pipeline). Otra cuestión interesante es que hay micros que pueden ejecutar instrucciones fuera de orden, con lo que ya te da por meterte a un manicomio porque te rompen todos los esquemas.
I have traveled across the universe and through the years to find Her. Sometimes going all the way is just a start.
Además vendo cosas!
Además vendo cosas!
- jotego
- Atari 1040 STf
- Mensajes: 657
- Registrado: 16 Ene 2013, 23:25
- Sistema Favorito: Atari ST
- primer_sistema: Amstrad CPC
- consola_favorita: Sony PlayStation 2
- Primera consola: Atari Lynx
- Ubicación: Valencia (España)
- Gracias dadas: 27 veces
- Gracias recibidas: 44 veces
- Contactar:
Re: ¿Emular la caché de la CPU?
Gracias por la explicación. Después de leerla, creo que el sentido para un emulador está en conseguir exactitud en los tiempos, por si algún programador ha usado el método del bucle tonto para hacer un retraso. En este caso la caché aceleraría la ejecución y modificaría el retraso. Esto podría ser crítico en una Nintendo 64 donde el sonido se hace entero por software. La ejecución desordenada, la tubería y la modificación del código en tiempo de ejecución los veo menos relevantes para un emulador de consola, aunque si buscas precisión en los tiempos puede hacer falta tenerlos en cuenta.
¿Quién está conectado?
Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados