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

x80: Тёплый ламповый (14 стр)

Advanced: Тема повышенной сложности или важная.

Страницы: 113 14 15 1618 Следующая »
#195
(Правка: 18:21) 18:19, 12 июня 2018

Mahagam
> а при наличии толстого кэша можно думать про упреждающее чтение.

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


#196
18:35, 12 июня 2018

Хм, ну и таки как я и думал ранее: 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.

#197
18:40, 12 июня 2018

=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 ядра процессора без внесения изменений в сами транзисторы. Однако, чтобы они смогли заработать - все эти инструкции уже должны быть в кэше. Если же инструкций в зоне досягаемости нет - элементы начинают простаивать, что выливается в потери времени. Если кэша нет - инструкции будут выполняться максимум с такой скоростью, с какой работает память. Никто не бежит впереди паровоза, потому что нельзя начать исполнять то, чего ещё нет, а чтобы оно появилось - нужно паровоза дождаться и получить инструкцию из памяти.
Кэш инструкций полезен только в том случае, если код много времени проводит в циклах - тогда на второй итерации цикла вместо того, чтобы отправлять паровоз за кодом, процессор сразу возьмёт инструкции из кэша, в котором они оказались записаны в ходе предыдущей итерации.
#198
18:45, 12 июня 2018

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

#199
18:48, 12 июня 2018

=A=L=X=
> когда очередь более сложного, чем первые RISC конвеера начинает опустошаться
Нет никакой очереди команд. Есть конвеер. Есть M стадий. Инструкции начинают на стадии 1 и заканчивают на стадии M. В течение одного такта инструкция может пройти не более одной стадии.
=A=L=X=
> есть еще шанс быстро всё поправить
Нет, никакого шанса нет. Новые инструкции начнут со стадии 1, и будут продвигаться точно так же, как если бы их загрузили сразу. Образовавшийся из-за простоя пузырь в конвеере никуда не уйдёт - он пройдёт через все стадии по очереди, и всё это время соответствующие элементы процессора будут простаивать.

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

#200
(Правка: 18:54) 18:53, 12 июня 2018

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

#201
(Правка: 19:06) 19:03, 12 июня 2018

Delfigamer
> Новые инструкции начнут со стадии 1

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

#202
20:10, 12 июня 2018

https://m.habr.com/post/182002/

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

#203
20:59, 12 июня 2018

=A=L=X=
> Во, отличная статья. Все почти спорные вопросы выше описаны.

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

#204
(Правка: 21:09) 21:02, 12 июня 2018

innuendo
Ну уж наверное не потому что первые убогие энстадийные конвееры часто впадали в столлы и не масштабировались дальше пяти-семи стадий без деградации? Да эти пять стадий давали буст по сравнению с процом без конвеера раза в два только изза столлов же.

#205
10:42, 13 июня 2018

Вoт странно, что в теме с идеей про конкретный процессор кипят такие страсти про всю остальную индустрию…

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

#206
11:20, 13 июня 2018

=A=L=X=
> Упреждающее чтение было известно задолго до кешей - см. буфер предвыборки
> инструкций 8086 про который я тут уже 10 раз говорил.
это пока скорость проца была примерно равна скорости памяти. 486-ой уже бы так не смог, так как с циклом 10ns он по 10 тактов ждал бы данные из памяти, которая по рандомным адресам тупила более 100ns. и только при наличии кэша, который может подсовывать данные ядру вовремя, можно думать, как при помощи упреждающего чтения забивать этот кэш данными которые будут востребованы в ближайшее время.

#207
12:13, 13 июня 2018

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).

#208
12:15, 13 июня 2018

=A=L=X=
я про данные. выборку кода прогнозировать чуть легче.

#209
(Правка: 12:21) 12:20, 13 июня 2018

Mahagam
> я про данные.

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

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

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

Страницы: 113 14 15 1618 Следующая »
ФлеймФорумПроЭкты