Если вы перейдете через 256 кодов операций через блок переключателей, вы будете делать косвенный скачок, который CPU не может предсказать хорошо, и это даст вам перерыв в конвейере для каждого кода операции.
Если работа по эмулированию кода операции является справедливым размером, то этот разрыв трубопровода может не иметь большого значения. Я подозреваю, что это так; код операции «load register» имитируется, по существу, только считыванием памяти, что не так много работы.
Вы можете приобрести некоторые видимые улучшения, добавив специальные тесты непосредственно перед блоком коммутатора, которые проверяют два или три наиболее часто встречающихся кода операций (возможно, LOAD, CMP, JMP условный) [Если opcode = JMP then ...] Эти тесты CPU могут обычно хорошо предсказывают. Если вы это сделаете, измерьте, измерьте, измерьте.
Смарт-трюк заключается в том, чтобы амортизировать расходы на разрыв трубопровода по нескольким инструкциям, если сможете. Если машина имеет много однобайтовых кодов операций, вы можете рассмотреть возможность перехода к следующему двум байтам кода порядка 65536. (Теперь вам нужно закодировать много корпусов коммутаторов, но многие из них - это по сути то же самое. Интересно, может ли ваш компилятор справиться с этим?) В реферате это сокращает затраты на разрыв трубопровода в два раза. Для конкретной машины с очень регулярным набором инструкций это может не купить вас много.
Однако у вас может быть не много однобайтовых кодов операций, но вам может потребоваться декодировать один или несколько байтов для каждой команды. X86 подобен этому (префикс, код операции, MODRM, SIB, смещение ...). Большой случай переключения должен работать очень хорошо для этого.
Возможно, правильно выровнять каждый корпус коммутатора на границе строки кэша. Если эмуляция команды проста, код, скорее всего, будет вписываться в строку кэша, и поэтому память видит только одну выборку для этой строки кэша. Если вы этого не сделаете, ваши эмуляции инструкций будут иметь более высокий шанс пересечения границы линии кэша, увеличив затраты на выборку памяти до двух. Это может не иметь значения для часто выполняемых инструкций, но код для редко исполняемых инструкций может выпасть из кеша. Это поможет, когда вы действительно столкнетесь с одним из них.
Последняя рекомендация: измерить, измерить, измерить.
_ «Разве это возможно быть настолько плотным с этими блоками opCode?» _ Это нам трудно понять. Во всяком случае, коммутатор/регистр с случаями, идущими от 0..255, скорее всего, будет оптимизирован компилятором на косвенный скачок с номером случая как индекс в таблицу переходов. Вы можете изучить выход сборки из своего компилятора, чтобы убедиться, что вам стоит попробовать оптимизировать что-либо. – Michael
Хотя это, безусловно, возможно, компилятор просто сохранит таблицу адресов прыжка, проиндексирует ее с помощью оператора switch и косвенно коснется. Ваш путь * может быть несколько быстрее, но он отнимает память (если только ваши заглушки на самом деле не нуждаются в 0x100 байтах), а * реальная * стоимость - это переход в любом случае, так как ему нужно предсказать предсказание цели, которое имеет тенденцию сосать. – EOF
да, они наверняка нуждаются во всех блоках 0x100bytes от 0 до 0x10000, и это всего лишь фиксированный код 64kb, поскольку он действует как «rom». Но какой прогноз? Все это определено, поскольку они являются фиксированными блоками с одинаковой длиной. Но хорошо. Теперь я вижу, что я дезинформировал всех. Я отредактирую вопрос. Это «НРАВИТСЯ» для случая с переключателем. – venge