реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> процессор сам меняет местами строки кода, как это возможно?
TigerSHARC
сообщение Mar 7 2018, 17:54
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 688
Регистрация: 4-09-09
Пользователь №: 52 195



https://www.youtube.com/watch?v=SIZmLPtcZiE&t=1112s

начало: 10:24
10:54 - "Хитрый процессор" может взять и переставить инструкции местами.

КАК?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 7 2018, 18:22
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(TigerSHARC @ Mar 7 2018, 19:54) *
начало: 10:24
10:54 - "Хитрый процессор" может взять и переставить инструкции местами.
КАК?

А что не понятного? Современные x86 внутри вроде как могут распараллеливать выполнение инструкций. Если между ними нет взаимозависимостей.
Опять же просто - при выполнении инструкции, записывающей в память, данные в ОЗУ могут оказаться не сразу, а пройдя через всевозможные кеши и межшинные мосты. И одни данные могут там быть раньше чем другие, даже если инструкции их писали в другом порядке.
Для борьбы с этим (когда нужно) уже даже в Cortex-M ввели инструкции барьеров.
Go to the top of the page
 
+Quote Post
@Ark
сообщение Mar 7 2018, 18:32
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 688
Регистрация: 13-05-16
Пользователь №: 91 710



Цитата(TigerSHARC @ Mar 7 2018, 20:54) *
https://www.youtube.com/watch?v=SIZmLPtcZiE&t=1112s
начало: 10:24
10:54 - "Хитрый процессор" может взять и переставить инструкции местами.
КАК?

Для начала, нужно понимать, что современные компиляторы могут сами "переставить инструкции" из своих соображений оптимизации, гарантируя при этом "'эквивалентность результата". Далее, уже сам процессор, разбирая команды из конвейера, может выполнять их, теоретически, в любом, удобном ему, порядке.
Опять же, гарантируя, эквивалентность результата, минимизируя, при этом, затраты, в первую очередь, временных ресурсов...
Если не знать и не понимать этих механизмов - рассуждения на эту тему превращаются в сплошное дилетантство... wink.gif
P.S. Если Вы пишите на ассемблере, и модифицируете инструкции " впереди себя", то результат будет зависеть от длины конвейера и его текущей загруженности в данный момент...

Go to the top of the page
 
+Quote Post
iosifk
сообщение Mar 7 2018, 19:00
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(TigerSHARC @ Mar 7 2018, 20:54) *
https://www.youtube.com/watch?v=SIZmLPtcZiE&t=1112s

начало: 10:24
10:54 - "Хитрый процессор" может взять и переставить инструкции местами.

КАК?

Я это видео не смотрел... sm.gif
Но точно знаю, как делается для Аналоговских DSP.
Значит хитрость вот какая может быть.
Представим:
инстр1
инстр2
инстр3
джамп...

Как это обычно выполняется?
сначала выполняются 3 инструкции, потом делается джамп, А потом несколько тактов процессор стоит, пока не перезагрузится конвейер из нового адреса. При этом в конвейере еще будут инструкции из старого адреса после команды "джамп", но их выполнение будет блокироваться процессором.
А теперь представим, что команду "джамп" компилятор передвинет вперед на то кол-во инструкций, какова глубина конвейера.
Как-то так:
инстр1
инстр2
джамп
инстр3..

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


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
@Ark
сообщение Mar 7 2018, 19:24
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 688
Регистрация: 13-05-16
Пользователь №: 91 710



Цитата(iosifk @ Mar 7 2018, 22:00) *
...
Ну а дальше если речь идет об оптимизирующем компиляторе, то надо читать об статическом и динамическом предсказании переходов...

На сколько мне известно, современные компиляторы "подстраиваются" под конкретный процессор, переставляя инструкции в нужном порядке.
Тем самым, обеспечивается нужный, зачастую "кривой" порядок инструкций, но оптимальный для данного процессора.
В итоге, обеспечивается максимальное быстродействие...

Go to the top of the page
 
+Quote Post
iosifk
сообщение Mar 7 2018, 19:49
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369



Цитата(@Ark @ Mar 7 2018, 22:24) *
На сколько мне известно, современные компиляторы "подстраиваются" под конкретный процессор, переставляя инструкции в нужном порядке.
Тем самым, обеспечивается нужный, зачастую "кривой" порядок инструкций, но оптимальный для данного процессора.
В итоге, обеспечивается максимальное быстродействие...

Ну да...
А если там еще есть микро-архитектура, это когда программист думает, что "вот по этому адресу есть регистр общего назначения"... А на самом деле, этих регистров там несколько и только компилятор знает, в каком хранится какое значение от предыдущих шагов программы. Поэтому к таким процессорам ассемблера нет вообще. У Шарков еще был, а у Блэкфинов - уже нет... И что там на самом деле делает процессор - тайна sm.gif


--------------------
www.iosifk.narod.ru
Go to the top of the page
 
+Quote Post
ArtemKAD
сообщение Mar 7 2018, 20:20
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 508
Регистрация: 26-06-06
Из: Киев
Пользователь №: 18 364



Цитата(iosifk @ Mar 7 2018, 21:49) *
Поэтому к таким процессорам ассемблера нет вообще. У Шарков еще был, а у Блэкфинов - уже нет... И что там на самом деле делает процессор - тайна sm.gif

Если есть GCC, то есть и Асм. Вот только отдельно его может не быть потому как даром не нужен.
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 8 2018, 02:48
Сообщение #8


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Не следует путать оптимизации конвейера и изменение порядка следования инструкций в процессоре. Первое выполняется компилятором на этапе компиляции - компилятор анализирует код и оптимизирует поток инструкций так, чтобы было как можно меньше простоев конвейера. Это то, что описал iosifk. Эта ситуация ярко проявляется на том же Blackfin'е. Процессор точно выполняет этот [оптимизированный] поток инструкций, никакой его самодеятельности тут нет - всё, что видно по листингу, будет исполняться процессором именно так. И, конечно, ничего не мешает писать тут на ассемблере, просто для достижения скорости вам придётся тоже переставлять инструкции, чтобы избежать stall'ов конвейера.

Более сложные процессорные ядра (современные x86, Cortex-A) поддерживают аппаратные оптимизации потока выполнения - т.е. могут менять физическое выполнение программы. Сюда относятся, в частности, изменение порядка следования инструкций (instruction reordering) и переименование регистров (register renaming). Как уже было сказано выше, если конвейер процессора получает инструкции на вход, которые не связаны по контексту друг с другом (т.е. нет взаимных связей), то процессор может поменять порядок их выполнения.

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

Но процессор "видит", что обе инструкции лезут в разные шины - одна на шину моста, другая - на шину памяти, поэтому он их запускает сразу, не ожидая, пока завершится первая. Далее идёт третья инструкция и она опять инструкция доступа в память, и опять процессор не ждёт, пока завершится первая инструкция (доступ к периферии), а только ждёт завершения второй (да и то не обязательно, от контекста зависит). Получается, что третья инструкция выполняется вперёд первой.

Это очень упрощенный пример, в реальности там ещё много факторов, которые влияют на порядок выполнения инструкций.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
jcxz
сообщение Mar 8 2018, 06:29
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(iosifk @ Mar 7 2018, 21:49) *
А на самом деле, этих регистров там несколько и только компилятор знает, в каком хранится какое значение от предыдущих шагов программы. Поэтому к таким процессорам ассемблера нет вообще. У Шарков еще был, а у Блэкфинов - уже нет...

Если компилятор знает, то будет знать и программист, пишущий на асме. Особых сложностей в этом нет. Ещё больше 10 лет назад писал на асме для TMS320VC5502: и уже там я распараллеливал поток инструкций - держал в голове что например одна инструкция (из пары) у меня выполняется на D-unit АЛУ, а вторая (из пары) - на A-unit АЛУ, поэтому они не должны использовать общие ресурсы (регистры), так как операции для этих разных АЛУ выполняются на разных стадиях конвеера и если будут взаимозависимости, то могут быть штрафы по нескольку тактов (на величину разности по конвееру между фазами исполнения разных инструкций).
Ничего сложного в этом нет. После некоторой практики запоминаешь на какой стадии конвеера выполняется какая инструкции и уже не думаешь в формате "эта инструкция стоит до, значит она выполнится до", а уже глядя на код понимаешь в каком такте после выборки команды она выполнится, и какой будет реальный порядок выполнения.
Но порядок выполнения инструкций при этом в c55xx не меняется - просто если последующая инструкция выполняется на более ранней стадии конвеера чем последующая, то на неё накладывается штраф на время разницы между этими двумя инструкциями. Возможно что в других ядрах как раз не штрафуется, а позволяется выполниться раньше.
Запись значений из регистров в память в ядрах C55xx всегда выполняется строго в одной и той же фазе конвеера. А именно об этом идёт речь в том видео, а не о реальной стадии конвеера на котором выполнится команда! Так что - вне зависимости от точки выполнения на конвеере, данные в память на C55xx всегда пишутся строго в том порядке, в каком стоят команды. Не знаю как с этим обстоят дела на других ядрах...
Но дальше идут кеши и разные регионы памяти, к каждому из которых своя шина, и каждый из которых может быть занят или не занят в этот момент другим bus-master-ом. Вот тут как раз вполне возможно рассогласование времён физической записи в ячейку памяти.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 8th July 2025 - 00:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.04795 секунд с 7
ELECTRONIX ©2004-2016