Начиная с Pentium x86 умеет в out-of-order. Самая "простая" реализация - берем поток команд, грузим одновременно в 10 конвейров в каждый свою, разбираем-маркируем вовлеченные исходные данные, есть зависимость по данным (помечены как ждущие коммита от других команд) - ждем результатов, нет зависимости - выполняем, ждем своей очереди на коммит, финальная проверка что ничего в исходных не поменялось - коммит в реальное состояние процессора. Поскольку все делалось в параллель в 10 блоках, то в какой-то такт может оказаться что завершилось несколько команд и надо просто реализовать широкий коммит их результатов. Все br и большинство jmp/jsr/rts/sob будут просто выполняться эквивалентно за 0 тактов (по факту - в фоне, во время исполнения предыдущих команд), заметная часть независимых mov и арифметики тоже, исключение за один такт - красота. Вот с флажками и автоинкрементом/декрементом может оказаться не так быстро, это да, усиливате зависимости. Но это все в порядке бреда. Для начала более реальная реализация на одну инструкцию за такт, там наработаются блоки декодирования, загрузки-записи и прочее, станет понятнее как оно дальше может быть. На FPGA с таким играться - это надо команду типа интеловской нанимать, а потрогать идею на CUDA - уже можно и самому пробовать.
По ветвлению интересно можно сделать, на каждое ветвление порождать свою ветку виртуального состояния процессора - конвейеров у нас много, можно тащить сразу две ветки, для выполненного и пропущенного условия перехода. Если дальше опять ветвления - новые ветки породить. По коммиту инструкции ветвления - ложные ветки убивать, верные коммитить в реальность. Такой себе мета-квантовый подход :)

