Les processeurs actuels utilisent des optimisations relativement lourdes pour gagner en performances. L’exécution dans le désordre, le renommage de registres, la prédiction de branchements et toutes les autres techniques d’exécution spéculative, sont clairement gourmandes en circuits, en portes logiques, en caches et autres tables de correspondance. Évidemment, les chercheurs ont déjà trouvé quelques alternatives : processeurs VLIW et EPIC, techniques d’exécution dans le désordre, etc. Mais il existe une alternative théorique relativement mal connue : les architectures découplées. Il existe plusieurs architectures de ce type, que nous allons aborder via quelques exemples.
Le découplage des accès mémoire.
L'idée qui se cache derrière les architectures découplées est de découpler l’exécution des instructions et le chargement des opérandes depuis la RAM. Les calculs et le chargement des opérandes se font chacun dans deux flux d'instruction séparés. Le découpage du programme en plusieurs flux peut s'effectue à la compilation. Les deux flux sont chacun exécutés sur un processeur séparé, un le processeur "access" en charge des accès mémoire et un processeur "execute" pour les calculs et des branchements. Le transfert des opérandes entre processeurs se fait par l'intermédiaire de mémoires tampons de type FIFOs, manipulées par le programmeur. Les transferts se font dans les deux sens : du processeur "access" vers le processeur "execute" pour les lectures, dans l'autre sens pour les écritures. Les branchements demandent cependant une synchronisation entre les deux flux d'instruction, afin de garantir qu'un branchement s’exécute bien au même moment dans les deux flux. Et toute la difficulté est de synchroniser les deux processeurs.
Cette technique n'est pas compatible avec l’exécution dans le désordre telle que vue dans les chapitres précédents, mais elle en reprend certains avantages. L'avantage principal est que la séparation en deux flux permet de profiter d'une forme limitée d’exécution dans le désordre, mais avec beaucoup moins de structures matérielles, moins de registres, moins de circuits. Les deux flux étant séparés, l'un peut continuer à s’exécuter alors que l'autre est en train d'attendre. Par exemple, le flux de calcul peut continuer à faire des calculs pendant que l'autre est coincé dans un accès mémoire de longue durée. Ou alors, le flux d'accès mémoire peut charger des données à l'avance, pendant que le flux de calcul est bloqué dans un calcul long (une division, par exemple). Cette forme de parallélisme est certes plus limitée que celle permise par l’exécution dans le désordre, mais le principe est là. 
Les échanges de données entre processeurs.
Prenons le cas d'une lecture : la lecture est démarrée par le processeur A, puis est transmise au processeur X. La transmission au processeur X se fait par l'intermédiaire d'une mémoire FIFO, la file de lecture de X ("X load queue", abréviée XLQ). Quand le processeur X a besoin d'un opérande lu depuis la mémoire, il vérifie si elle est présente dans l'XLQ et se met en attente tant que ce n'est pas le cas.
Pour les écritures, l'adresse de l'écriture est calculée par le processeur A, tandis que la donnée à écrire est calculée par le processeur X, et les deux ne sont pas forcément disponibles en même temps. Pour cela, les adresses et les données sont mises en attente dans deux mémoires tampons qui coopèrent entre elles. La première est intégrée dans le processeur A et met en attente les adresses calculées : c'est la file d’écriture des adresses ("store address queue", ou SAQ). La seconde met en attente les données à lire, et relie le processeur X au processeur A : c'est la file d’écriture de X ("X store queue", ou XSQ). Quand l'adresse et la donnée sont disponibles en même temps, l'écriture est envoyée à la mémoire ou au cache.
Les échanges entre processeurs peuvent aussi se faire sans passer par des files de lecture/écriture. Cela peut servir pour diverses scénarios. Par exemple, le calcul d'une adresse sur le processeur A peut utiliser des données calculées par le processeur X. Pour cela, les échanges s'effectuent par copies inter-processeurs de registres. Un registre peut être copié du processeur A vers le processeur X, ou réciproquement. Pour utiliser cette unité de copie, chaque processeur dispose d'une instruction COPY.
Les branchements.
Les branchements sont présents à des endroits identiques dans les deux flux, ce qui fait que les structures de contrôle présentes dans un programme sont présentes à l'identique dans l'autre, etc. Or, les branchements doivent donner le même résultat dans les deux processeurs. Pour cela, le résultat d'un branchement sur un processeur doit être transmis à l'autre processeur. Pour cela, on trouve deux files d'attente :
Il faut noter que le processeur peut se trouver définitivement bloqué si l'AEQ et l'EAQ sont toutes deux totalement remplies ou totalement vide. Pour éviter cette situation, les compilateurs doivent compiler le code source d'une certaine manière.
Pour en savoir, voici quelques liens utiles.
Le découplage des branchements.
L'idée qui consiste à séparer un programme en deux flux a été adaptée pour séparer d'un côté un flux de branchements et un flux de calculs/accès mémoires. L'article « The effectiveness of decoupling » décrit l'architecture ACRI-1, qui découple accès mémoire, branchements et calculs. Cette architecture a été implémentée en matériel quelques années après la publication de l'article. Outre les processeurs X et A, on trouve un processeur maitre pour les branchements, qui répartit le travail à effectuer sur les deux autres processeurs. Les processeurs A et X ne peuvent qu'exécuter des boucles assez spéciales : elles ne doivent pas contenir de branchements ou de boucles imbriquées à l'intérieur. Le processeur maitre gère la répartition des boucles sur les deux autres processeurs, ce qui permet de se passer des files d'attentes pour les branchements. Pour demander l’exécution d'une boucle, le processeur maître envoie ce qu'on appelle un bloc de chargement d’instructions ("instruction fetch block" ou IFB), qui contient un pointeur sur la première instruction de la boucle, le nombre d'instructions de la boucle et le nombre d'itérations. L'envoi d'un IFB sur les mémoires tampons est réalisé sur ordre d'une instruction machine spécialisée.

Fonctionnement d'un ordinateur/Les bus et liaisons point à point (généralités)