El AVR XMega tiene 16 registros GPIO en el espacio de E / S además de su SRAM interna. Es interesante que la sincronización de las instrucciones de LD difiera de estas ubicaciones: acceder al espacio de E / S (bastante grande) es más rápido que acceder a la SRAM interna.
Esto se puede observar más o menos en la documentación del conjunto de instrucciones: enlace (de la página 22) (Más bien "menos", ya que es bastante ambiguo).
Sin estar seguro de cómo funciona la sincronización, hice pruebas con el hardware real, midiendo los tiempos de varias instrucciones.
Accediendo a la SRAM:
Mega XMega
LD reg, ptreg 2cy 2cy
LD reg, ptreg+ 2cy 2cy
LD reg, -ptreg 2cy 3cy
LDD reg, ptreg+imm 2cy 3cy
LDS reg, imm16 2cy 3cy
ST ptreg, reg 2cy 1cy
ST ptreg+, reg 2cy 1cy
ST -ptreg, reg 2cy 2cy
STD ptreg+imm, reg 2cy 2cy
STS imm16, reg 2cy 2cy
Al acceder al área de E / S (probado con los registros GPIO y UART), las cargas son un ciclo más rápidas:
Mega XMega
LD reg, ptreg 2cy 1cy
LD reg, ptreg+ 2cy 1cy
LD reg, -ptreg 2cy 2cy
LDD reg, ptreg+imm 2cy 2cy
LDS reg, imm16 2cy 2cy
ST ptreg, reg 2cy 1cy
ST ptreg+, reg 2cy 1cy
ST -ptreg, reg 2cy 2cy
STD ptreg+imm, reg 2cy 2cy
STS imm16, reg 2cy 2cy
¿Alguien podría darnos una idea de por qué podría haber sido diseñado de esta manera? La diferencia de rendimiento es bastante significativa para las tareas que hacen un uso intensivo de la memoria, y los 16 registros GPIO no son muchos si alguien necesita una RAM más rápida (mientras que el espacio de E / S es enorme en comparación, aparentemente completamente capaz de operar con la sincronización más rápida, lo cual es elección de diseño Realmente no puedo entender si este acceso más rápido requería hardware más costoso).
Un caso particularmente malo es que las cargas de desplazamiento de 3 ciclos son muy frecuentes, e incluso AVR-GCC parece inclinarse hacia el uso de esas en lugar de tratar de caminar a través de las áreas de memoria con post-incrementos al optimizar.