Флейм
GameDev.ru / Флейм / Форум / CISC-x80: ПРАвәльный 8-битный «ДОМАШНИЙ» (псевдо-совместимый с PC-XT / CP/M-80 / DOS) (14 стр)

CISC-x80: ПРАвәльный 8-битный «ДОМАШНИЙ» (псевдо-совместимый с PC-XT / CP/M-80 / DOS) (14 стр)

Advanced: Тема повышенной сложности или важная.
Страницы: 110 11 12 13 14 15 Следующая »
=A=L=X=Постоялецwww12 июня 201818:19#195
Mahagam
> а при наличии толстого кэша можно думать про упреждающее чтение.

Упреждающее чтение было известно задолго до кешей - см. буфер предвыборки инструкций 8086 про который я тут уже 10 раз говорил.
Кеши - вещь, про них я тоже говорил. А ведь есть еще несколько уровней кеша - то есть когда очередь более сложного, чем первые RISC конвеера начинает опустошаться от отсутствия команд есть еще шанс быстро всё поправить слазив в кеш второго там уровня, не обязательно может оказаться курить простаивая сотни тактов, но если бы заполненной очереди не было - курили бы ожидая десяток другой тактов.
В общём усложнилось всё и большой отпечаток на всём оставила именно медленность памяти.

Правка: 12 июня 2018 18:21

=A=L=X=Постоялецwww12 июня 201818:35#196
Хм, ну и таки как я и думал ранее: https://en.wikipedia.org/wiki/Prefetch_input_queue
However, these disadvantages are greatly offset by the improvement in processor execution time. After the introduction of prefetch instruction queue in the 8086 processor, all successive processors have incorporated this feature.
DelfigamerПостоялецwww12 июня 201818:40#197
=A=L=X=
> Out-of-order у него прямо оговаривается способность переставлять всё местами
> чтобы убрать как можно больше простоев
Пропустил изначально, так что поясняю.
Речь идёт не о кэш-промахах, а о простое модулей процессора - ALU, FPU, шина - во время выполнения команд.
Представим, что у нас процессор, внутри которого лежат 4 ALU.
При выполнении кода вида
int dot(int4 v0, int4 v1)
{
  v0 = mul4i(v0, v1);
  v1 = swizzle4(v0, 2, 3, 0, 0);
  v0 = add4i(v0, v1);
  v1 = swizzle4(v0, 1, 0, 0, 0);
  v0 = add1i(v0, v1);
  int r3 = getelementi(v0, 0);
  return r3;
}
на большинстве инструкций работают все 4 вычислителя - это хорошо.
Если же выполняется код вида
int strcmp(char const* r4, char const* r5)
{
start:
  int r3 = loadbyte(r4);
  int r6 = loadbyte(r5);
  r3 = r3 - r6;
  r4 = r4 + 1;
  r5 = r5 + 1;
  if (r3 != 0)
    return r3;
  goto start;
}
то каждая инструкция задействует не более одного ALU, следовательно - три оставшихся сидят в сторонке и ничего не делают. Это нехорошо.
Обратим внимание - арифметические инструкции по вычислению r3, r4 и r5 не зависят друг от друга и, в принципе, могут быть произведены параллельно.
Процессоры с out-of-order execution так и делают - загружают все три инструкции и выполняют их одновременно, в течение одного такта.
Поскольку транзисторы на входной сигнал реагируют не сразу, а с задержкой, то существует минимальное время, которое потратится на обработку сигнала - будь то разбор инструкции, арифметические вычисления, запись в регистр или что-то ещё.
Идея конвеера состоит в том, что выполнение одной инструкции разделяется на несколько независимых стадий. Без конвеера, чтобы начать выполнять инструкцию N+1, нужно сначала дождаться полного завершения выполнения инструкции N - что в сумме займёт, например, 20 наносекунд. Однако, с конвеером, первую стадию инструкции N+1 можно запускать сразу после того, как закончится первая стадия инструкции N - даже если у инструкции N есть ещё незавершённые стадии впереди. По такой схеме, длина такта ограничена не полным выполнением инструкции, а только полным выполнением одной стадии - всего лишь 4 наносекунды. В итоге получаем возможность на тех же транзисторах собрать процессор с частотой в пять раз выше.
Идея OOE состоит в том, чтобы несколько инструкций, которые не пересекаются по данным, выполнять не друг за другом, а параллельно. Или в обратном порядке. Если инструкция N ждёт результатов работы от N-1, а для инструкции N+1 всё уже готово - процессор вполне способен начать и даже завершить выполнение N+1 прежде, чем N успеет начаться. Теперь, у нашего процессора всё тот же тактовый период - 4нс - но зато за один такт теперь можно выполнять сразу по несколько инструкций.
Обе техники - это методы повышения MIPS ядра процессора без внесения изменений в сами транзисторы. Однако, чтобы они смогли заработать - все эти инструкции уже должны быть в кэше. Если же инструкций в зоне досягаемости нет - элементы начинают простаивать, что выливается в потери времени. Если кэша нет - инструкции будут выполняться максимум с такой скоростью, с какой работает память. Никто не бежит впереди паровоза, потому что нельзя начать исполнять то, чего ещё нет, а чтобы оно появилось - нужно паровоза дождаться и получить инструкцию из памяти.
Кэш инструкций полезен только в том случае, если код много времени проводит в циклах - тогда на второй итерации цикла вместо того, чтобы отправлять паровоз за кодом, процессор сразу возьмёт инструкции из кэша, в котором они оказались записаны в ходе предыдущей итерации.
=A=L=X=Постоялецwww12 июня 201818:45#198
Delfigamer
> Однако, чтобы они смогли заработать - все эти инструкции уже должны быть в кэше.
Вот вот - именно поэтому их и стараются извлекать загодя и набивать в буфер побольше, чтобы инпут лаг так сказать больший можно было пережить без простаиваний.
Вообще даже самый тупейший конвеер включает в себя префетчинг хотя бы одной инструкции - потому что первая фаза конвеера как раз извлечение инструкции, то есть её можно рассматривать как раз как префетчинг для следующей фазы.
Но стараются увеличить, см. выше. И это отдельный от кеша механизм - дело тут не в кеше, а именно в желании иметь сразу на входе конвеера готовые к считыванию со регистровой скоростью коды инструкций. Не как из кеша, а как из регистра.
DelfigamerПостоялецwww12 июня 201818:48#199
=A=L=X=
> когда очередь более сложного, чем первые RISC конвеера начинает опустошаться
Нет никакой очереди команд. Есть конвеер. Есть M стадий. Инструкции начинают на стадии 1 и заканчивают на стадии M. В течение одного такта инструкция может пройти не более одной стадии.
=A=L=X=
> есть еще шанс быстро всё поправить
Нет, никакого шанса нет. Новые инструкции начнут со стадии 1, и будут продвигаться точно так же, как если бы их загрузили сразу. Образовавшийся из-за простоя пузырь в конвеере никуда не уйдёт - он пройдёт через все стадии по очереди, и всё это время соответствующие элементы процессора будут простаивать.

То, о чём ты думаешь - это L1 instruction cache. Это не очередь. Это кэш.
Из этого кэша инструкции сразу отправляются в ядро.
Если инструкций нет - начинается догрузка из следующего уровня, а ядро тем временем стоит и курит.

DelfigamerПостоялецwww12 июня 201818:53#200
=A=L=X=
> Но стараются увеличить, см. выше. И это отдельный от кеша механизм - дело тут
> не в кеше, а именно в желании иметь сразу на входе конвеера готовые к
> считыванию со регистровой скоростью коды инструкций. Не как из кеша, а как из
> регистра.
Если L1 кэш медленный - то ты ничего с этим не поделаешь.
Ну и что, что у тебя посередине стоит быстрая очередь? Заполняться эта очередь всё равно будет из медленного кэша, поэтому в конечном итоге весь процессор всё равно будет работать со скоростью медленного кэша, и никакие очереди тебе в будущее заглянуть не дадут.

Правка: 12 июня 2018 18:54

=A=L=X=Постоялецwww12 июня 201819:03#201
Delfigamer
> Новые инструкции начнут со стадии 1

Окай. Начинают - а в конце стадий еще пять штук нагружающих сумматоры, потом пузырь, и вот наша подоспевшая инструкция начала со стадии 1. Но когда она дошла до того что ей нужно задействовать сумматор тот оказывается еще занят теми стадиями в конце - пузырь помешал задействовать сумматор оптимально тогда? Есть ли тогда вообще разница где находится пузырь - в середине или в начале?

Правка: 12 июня 2018 19:06

=A=L=X=Постоялецwww12 июня 201820:10#202
https://m.habr.com/post/182002/

Во, отличная статья. Все почти спорные вопросы выше описаны.
И то, что есть отдельно кеш инструкций и очередь префетчинга инструкций.
И то, что конвеер с внеочередным исполнением весьма и весьма существенно иначе работает отлично от примитивных энстадийных конвееров и в нем уже не стадии, а очередь мюопов которую еще и реордерит ядро постоянно.
Описаны ситуации, что делением мюопов на два потока спекулятивных гасится часть негатива неверного предсказания перехода и т.п.

innuendoПостоялецwww12 июня 201820:59#203
=A=L=X=
> Во, отличная статья. Все почти спорные вопросы выше описаны.

теперь ты понял, почему я хочу RISC ?

=A=L=X=Постоялецwww12 июня 201821:02#204
innuendo
Ну уж наверное не потому что первые убогие энстадийные конвееры часто впадали в столлы и не масштабировались дальше пяти-семи стадий без деградации? Да эти пять стадий давали буст по сравнению с процом без конвеера раза в два только изза столлов же.

Правка: 12 июня 2018 21:09

AlikberovПостоялецwww13 июня 201810:42#205
Вoт странно, что в теме с идеей про конкретный процессор кипят такие страсти про всю остальную индустрию…

P.S.: Хотя, гуглом нашёл форум, где CISC/RISC приравнивают к дури…

MahagamПостоялецwww13 июня 201811:20#206
=A=L=X=
> Упреждающее чтение было известно задолго до кешей - см. буфер предвыборки
> инструкций 8086 про который я тут уже 10 раз говорил.
это пока скорость проца была примерно равна скорости памяти. 486-ой уже бы так не смог, так как с циклом 10ns он по 10 тактов ждал бы данные из памяти, которая по рандомным адресам тупила более 100ns. и только при наличии кэша, который может подсовывать данные ядру вовремя, можно думать, как при помощи упреждающего чтения забивать этот кэш данными которые будут востребованы в ближайшее время.
=A=L=X=Постоялецwww13 июня 201812:13#207
Mahagam
> 486-ой уже бы так не смог
https://gamedev.ru/flame/forum/?id=236084&page=14#m196
After the introduction of prefetch instruction queue in the 8086 processor, all successive processors have incorporated this feature.

https://gamedev.ru/flame/forum/?id=236084&page=14#m202

Поехали, вы – инструкция в программе, и эта программа запускается.
Вы терпеливо ждете, пока IP начнет указывать на вас для последующей обработки. Когда IP указывает примерно за 4кб до вашего расположения, или за 1500 инструкций, вы перемещаетесь в кэш инструкций. Загрузка в кэш занимает некоторое время, но это не страшно, так как вы ещё нескоро будете запущены. Эта предзагрузка (prefetch) является частью первого этапа конвейера.
Тем временем IP указывает всё ближе и ближе к вам, и, когда он начинает указывать за 24 инструкции до вас, вы и пять соседних команд отправляетесь в очередь инструкций (instruction queue).

MahagamПостоялецwww13 июня 201812:15#208
=A=L=X=
я про данные. выборку кода прогнозировать чуть легче.
=A=L=X=Постоялецwww13 июня 201812:20#209
Mahagam
> я про данные.

А я всегда говорил про

буфер предвыборки инструкций 8086

Короче всё что я говорил выше про то как конвеер борется с латентностями всякими памяти - всё вообще оказалось верно и нормально.
Вот развели из одной незначительной части фразы срач на три страницы.
Но с другой стороны истина высветилась чётче. Так что не зря.

Правка: 13 июня 2018 12:21

Страницы: 110 11 12 13 14 15 Следующая »

/ Форум / Флейм / ПроЭкты

2001—2018 © GameDev.ru — Разработка игр