Вы правы, современный x86 декодирует add dword [mem], 1
до 3 моп: загрузка, добавление ALU и хранилище.
Эти 3 зависимые операции не могут выполняться одновременно, поскольку более поздние должны ждать результата более ранней.
Но выполнение независимых инструкций может перекрываться, и современные процессоры очень настойчиво ищут и используют «параллелизм на уровне команд», чтобы запустить ваш код быстрее, чем 1 моп за такт. См. этот ответ для введения в то, что одно ядро ЦП может делать параллельно , со ссылками на другие материалы, например, Руководство по микроархитектору x86 Агнера Фога , и описания Дэвида Кантера Песчаный мост и Бульдозер .
Но если вы посмотрите на семейства микроархитектур Intel P6 и Sandybridge, хранилище на самом деле представляет собой отдельный адрес магазина и данные хранилища . Uop-адрес хранилища не зависит от загрузки или ALU и может записать адрес хранилища в буфер хранилища в любое время. (Руководство по оптимизации Intel называет его буфером порядка памяти).
Для увеличения пропускной способности внешнего интерфейса, адреса хранения и данные хранилища могут декодироваться как пара с микроплавлением. Для add
, так же как и для операции load + alu, процессор Intel может декодировать add dword [rdi], 1
в 2 мопа слитых доменов. (Та же самая нагрузка + добавление micro-fusion работает для декодирования add eax, [rdi]
для одного мопа, поэтому его может декодировать любой из «простых» декодеров, а не только «сложный» декодер, который может обрабатывать многопользовательские инструкции. конец узких мест).
Именно поэтому add [mem], 1
более эффективен, чем inc [mem]
на процессорах Intel, хотя inc reg
столь же эффективен (но меньше), чем add reg,1
. (inc
не может микропереключить свою нагрузку + inc, что устанавливает флаги иначе, чем add
). Инструкция INC против ADD 1: это имеет значение?
Но это только помогает внешнему интерфейсу быстрее вводить мопы в планировщик; нагрузка по-прежнему должна выполняться отдельно от надстройки.
Но нагрузка с микроплавлением не должна ждать, пока все остальные входные данные инструкции будут готовы. Рассмотрим инструкцию типа add [rdi], eax
, где RDI и EAX являются входными данными для инструкции, но EAX не требуется, пока ALU не добавит uop. Загрузка может быть выполнена, как только загрузочный адрес будет готов, и есть свободный модуль выполнения загрузки (AGU + доступ к кешу). См. Также Как запланировано выполнение x86-мопов? .
регистры считываются в Decode uOp, Store / Load in Memory uOp, и мы позволяем себе взять значение регистра в Memory uOp
Все текущие микроархитектуры x86 используют неупорядоченное выполнение с переименованием регистров (алгоритм Томасуло). Инструкции переименовываются и выдаются в неработающую часть ядра (ROB и планировщик).
Физический регистровый файл не читается, пока инструкция не «отправлена» из планировщика в исполнительный модуль. (Или для недавно сгенерированных входных данных, переадресованных из других мопов.)
Независимые инструкции могут перекрывать свое выполнение . Например, процессор Skylake может поддерживать пропускную способность 4 мопов в слитых доменах / 7 неиспользуемых доменов за такт, включая 2 загрузки + 1 хранилище, в тщательно продуманном цикле :
.loop: ; HSW: 1.12c / iter. SKL: 1.0001c
add edx, [rsp] ; 1 fused-domain uop: micro-fused load+add
mov [rax], edi : 1 fused-domain uop: micro-fused store-address+store-data
blsi ebx, [rdi] : 1 fused-domain uop: micro-fused load+bit-manip
dec ecx
jnz .loop ; 1 fused-domain uop: macro-fused dec+branch runs on port 6
Процессоры семейства Sandybridge имеют L1d-кэш, способный на 2 чтения + 1 запись в такт. (До Haswell только 256-битные векторы могли работать с пределом пропускной способности AGU. См. Как кэширование может быть таким быстрым? .)
Пропускная способность фронт-энда семейства Sandybridge составляет 4 мопа слитых доменов за такт, и у них есть множество исполнительных блоков в бэк-энде для обработки различных комбинаций команд. (У Haswell и более поздних версий есть 4 целочисленных ALU, 2 порта загрузки, порт хранилища данных и выделенный AGU хранилища для простых режимов адресации хранилища. Таким образом, они часто могут быстро «догнать» после выполнения остановки кэша, что быстро комната в окне не в порядке, чтобы найти больше работы.)