Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.217.65.190] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Установил супер профайлер AQTime 6.21, который анализирует время работы кода построчно.
Взял в Delphi написал тупой код см. вложение (большие числа слева это машинные циклы на выполнение данной инструкции), и профайлер показал, что DEC работает медленнее чем sub. Как это? Прикреплённый файлpic.JPG (41,88 Кбайт, скачиваний: 511) |
Сообщ.
#2
,
|
|
|
На время выполнения инструкций влияют еще и предыдущие. Попробуй попереставлять инструкции местами и будешь приятно удивлен, как меняется их доля Вообще же DEC не модифицирует регистр флагов полностью, поэтому возможны задержки из-за предыдущих команд, затрагивающих этот регистр. Собственно поэтому на современных камнях не рекомендуют использование DEC.
|
Сообщ.
#3
,
|
|
|
Достаточно заглянуть в маны от интела, найти там подробнейшую информацию по инструкциям.
|
Сообщ.
#4
,
|
|||||||||||||
|
Цитата Intel® Pentium® 4 and Intel® Xeon™ Processor Optimization.pdf Т.е. DEC занимает полный цикл, SUB - только полуцикл.
|
Сообщ.
#5
,
|
|
|
Цитата DelphiLexx @ Установил супер профайлер AQTime 6.21, который анализирует время работы кода построчно На современных суперскалярных компах с внеочередным исполнением команд, достоверное профилирование на уровне каждой асм-команды практически невозможно. И твой пример это лишний раз подтверждает, т.к. самыми тормозными инструкциями в приведенном коде являются call и ret, а твой "супер профайлер" считает, что на исполнение call тратится времени меньше, чем на безобидный dec PS: Как-то на васме аналогичный вопрос всплывал по AMD CodeAnalyst - см. ответы #3 и #9 Добавлено Цитата Qraizer @ Т.е. DEC занимает полный цикл, SUB - только полуцикл. Это справедливо только для Pentium 4, а в P6 и AMD свои хитрости, и если после dec нет обращения к флагу CF (а в приведенном куске его нет), то dec отрабатывает также быстро, как и sub. |
Сообщ.
#6
,
|
|
|
Ну так я и сослался на доку по процессорам конретной архитектуры.
Вообще, даже заняв полный цикл АЛУ, не факт, что будет падение производительности. Это зависит ещё от востребованности этого АЛУ другими микроопсами. Там на картинке видно множество АЛУ-команд рядышком. И, кстати, call/ret по картинке же на деле могут предсказываться с 100% точностью за минусом самого первого call. Медлительность ret объясняется, наверно, зависимостью по стеку от предшествующих pop. |
Сообщ.
#7
,
|
|
|
Цитата Qraizer @ И, кстати, call/ret по картинке же на деле могут предсказываться с 100% точностью за минусом самого первого call. Медлительность ret объясняется, наверно, зависимостью от предшествующих pop по стеку Во-первых, предсказание тут ни причем, т.к. оно влияет только на задержку исполнения следующих за call\ret команд, а сами call\ret как ни крути состоят не из одной микрооперации как sub, и не из двух как dec в P4, а не менее чем из 3-х - запись\чтение адреса возврата, изменение esp и собс-но сам jmp (несмотря на предсказание, jmp как моп по любому должен "выполниться" только ради того, чтобы "отметиться" ) Добавлено Еще раз подчеркну, что "построчный" анализ на уровне отдельных команд не может дать достоверной картины. Не знаю, как там в AQTime, а в справке по CodeAnalyst поясняется, что все это "построчное" профилирование выполняется путем прерывания процессора в случайные моменты времени и анализа того, на какой инструкции произошел останов. Спрашивается с какой стати он будет происходить именно на самой медленной инструкции, а не на следующей за ней ? Разве команда не обязана завершиться, если прерывание пришло в момент ее исполнения. Может тут dec и дает завышенное значение потому, что она идет вслед за ret и можно лишь примерно указать "проблемное" место в районе ret->dec Добавлено Кстати, вообще вопрос интересный, каким образом можно прервать (извне) исполнение кода на произвольной команде, если проц обрабатывает одновременно до трех простых одномоповых команд - они и с декодера могут поступать одновременно по 3 шт. и также тройками уходят в отставку (считаются выполненными) - спрашивается как ("на каком таком основании") внешнее прерывание может вклиниться и разбить эту тройку ? |
Сообщ.
#8
,
|
|||||||||||||||||||
|
Цитата Intel® Pentium® 4 and Intel® Xeon™ Processor Optimization.pdf Ну да, Latency велико, но Throughput вполне на уровне. Два порта исполнения ещё занимают... В общем, вполне терпимо.
Вот ещё из старого нарыл. Цитата Pentium II and Pentium III Processors Instruction to Decoder Specification
Добавлено Что касается внешних событий, нужно почитать. Думаю, внешние прерывающие сигналы просто отрабатывают, как соответствующие программные аналоги, эдакими неявными int. |
Сообщ.
#9
,
|
|
|
Цитата Qraizer @ Думаю, внешние прерывающие сигналы просто отрабатывают, как соответствующие программные аналоги, эдакими неявными int Программные аналоги отличаются тем, что их положение среди других команд строго определено. А внешние сигналы приходят в произвольный момент времени, когда в конвеере на разных стадиях уже крутится десяток-другой команд, причем простые одномоповые команды поступают и покидают конвеер по 3 шт. за такт, поэтому и не понятно как внешний сигнал может нарушить это "триединство", т.к. если привязываться к тактам, то "эдакий неявный int" можно вставить либо до, либо после очередной тройки команд. Загадка, одним словом... |
Сообщ.
#10
,
|
|
|
Я ж говорю, почитать надо. Помню, что i486 распознавал активность по сигналам INTR и NMI только на границах инструкций, кроме тех, которые специально оговорены, что после них этого не делается. Например, команды пересылки в SS, кроме LSS, запрещают восприятие активности по этим входам, что даёт возможность атомарно изменить пару регистров SS:(E)SP целиком. Так что последовательность
ALIGN 16 mov eax, OFFSET [newStack] mov ss, SEG [newStack] mov esp, eax |
Сообщ.
#11
,
|
|
|
Цитата Qraizer @ Я ж говорю, почитать надо Где ? В официальных мануалах о таких тонкостях не пишут, видимо считая это несущественным для асинхронных прерываний. Те же общие слова о границах инструкций, определяемых на стадии их отставки (retirement): Цитата The ability of a P6 family processor to speculatively execute instructions does not affect the taking of interrupts by the processor. Interrupts are taken at instruction boundaries located during the retirement phase of instruction execution; so they are always taken in the “in-order” instruction stream. А то, что в "суперскалярах" в отставку могут уходить две-три инструкции одновременно - ни слова (в контексте определения момента прерывания) |
Сообщ.
#12
,
|
|
|
Ну почему не пишут:
Цитата Intel® 64 and IA-32 Architectures Software Developer’s Manual \ Volume 3A System Programming Guide Part 1 Исходя из этого можно сделать тот же вывод. Всё выбранное и декодированное после инструкции, на которой был замечен INTR, отбрасывается (ну или по меньшей мере не учитывается), процессор отрабатывает эту последнюю команду целиком, ордерит своё состояние и переходит к INT n, соответствующей исходной INTR. 6.15 EXCEPTION AND INTERRUPT REFERENCE ... Interrupts 32 to 255—User Defined Interrupts ... Description ... ... Saved Instruction Pointer The saved contents of CS and EIP registers point to the instruction that follows the INT n instruction or instruction following the instruction on which the INTR signal occurred. Program State Change A program-state change does not accompany interrupts generated by the INT n instruction or the INTR signal. The INT n instruction generates the interrupt within the instruction stream. When the processor receives an INTR signal, it commits all state changes for all previous instructions before it responds to the interrupt; so, program execution can resume upon returning from the interrupt handler. |
Сообщ.
#13
,
|
|
|
Qraizer, ты че - не въезжаешь или издеваешься ?!
Процессор - тактируемое устройство, поэтому внешний сигнал INTR может быть зафиксирован только с точностью до такта (об этом кстати однозначно говориться в спецификациях). Но за 1 такт в суперскалярах может декодироваться и исполняться до 3-х команд одновременно. Это означает, что команды могут группироваться в неразрывные пары или тройки, обрабатываемые за 1 такт, и соотв-но INTR м.б. "замечен" не на любой произвольной команде, а только на границах таких неразрывных групп. В частности в приведенном примере #1 первые две команды в начале цикла (lea eax и mov edx) являются простыми одномоповыми и независимыми (ни друг от друга, ни от каких предыдущих команд), поэтому они декодируются, исполняются и уходят в отставку всегда парой и соотв-но внешний INTR (по идее) никак не может вклиниться внутрь этой пары таким образом, чтобы lea оказалась выполненной, а mov нет. Соотв-но EIP после INTR не может указывать на команду mov, т.к. в начале такта ухода этой пары в отставку EIP указывает на lea, а в конце такта сразу перескакивает на след.команду call |
Сообщ.
#14
,
|
|
|
Я прекрасно въезжаю в то, что ты хочешь сказать. Я не понимаю, что тебе тут не понятно. Ну и не получится никогда в жизни, чтоб INTR разбила эту твою пару пополам, вклинившись между ними. Ну и что? Да, отберуться из потока исполнения и будут переданы декодерам одновременно. Если я никогда не увижу в стеке EIP указывающий на MOV, кроме как если взведён TF или на неё указывает один из DRx, что я потеряю? Обработка же аппаратного прерывания всё равно описана, и описана чётко.
|
Сообщ.
#15
,
|
|
|
Цитата Qraizer @ Я прекрасно въезжаю в то, что ты хочешь сказать. Я не понимаю, что тебе тут не понятно А зачем тогда приводишь цитаты не имеющие отношения к моему вопросу и вынуждаешь по три раза повторять одно и то же ? А непонятно мне то, что если AQTime и CodeAnalyst юзают внешние прерывания для определения процента времени выполнения инструкциий, почему для всех команд получается ненулевой процент - случайное стечение обстоятельств, или все же прерывание может вклиниваться в пары-тройки, или же существует какой-то более продвинутый метод "построчного" профилирования ? |