измерять время выполнения одной инструкции - PullRequest
2 голосов
/ 17 апреля 2010

Есть ли способ использовать C или ассемблер или, возможно, даже C #, чтобы получить точную оценку того, сколько времени требуется для выполнения инструкции ADD?

Ответы [ 4 ]

11 голосов
/ 17 апреля 2010

Да, вроде, но это нетривиально и дает результаты, которые почти бессмысленны, по крайней мере, для большинства современных процессоров.

На относительно медленных процессорах (например, по сравнению с оригинальным Pentium в линейке Intel, все еще верно для большинства небольших встроенных процессоров) вы можете просто посмотреть в техническом описании процессора, и он (обычно) скажет вам, сколько тактов ожидать. Быстро, просто и легко.

На современном настольном компьютере (например, Pentium Pro или новее) жизнь не столь проста, как почти . Эти процессоры могут одновременно выполнять несколько инструкций и выполнять их не по порядку, если между ними нет никаких зависимостей. Это означает, что вся концепция времени, занимаемого одной инструкцией, становится почти бессмысленной. Время, необходимое для выполнения одной инструкции, может и будет зависеть от инструкций, которые ее окружают.

Тем не менее, да, если вы действительно хотите, вы можете (обычно - в зависимости от процессора) что-то измерить, хотя возникает вопрос, сколько именно это действительно будет значить. Даже получить такой результат, который только близок к бессмысленно, а не совершенно бессмысленно, не тривиально. Например, на чипе Intel или AMD вы можете использовать RDTSC для измерения времени. Это, к сожалению, может быть выполнено не по порядку, как описано выше. Чтобы получить значимые результаты, вам необходимо окружить его инструкцией, которая не может быть выполнена не по порядку («инструкция сериализации»). Наиболее распространенным вариантом для этого является CPUID, поскольку это одна из немногих инструкций сериализации, которая доступна для программ в «пользовательском режиме» (т.е. кольцо 3). Это добавляет некоторые изюминки: хотя, как документировано Intel, первые несколько раз процессор выполняет CPUID, это может занять больше времени, чем последующие. Таким образом, они рекомендуют вам выполнить это три раза, прежде чем использовать его для сериализации вашего времени. Поэтому общая последовательность запускается примерно так:

.align 16
CPUID
CPUID
CPUID
RDTSC
; sequence under test
Add eax, ebx
; end of sequence under test
CPUID
RDTSC

Затем вы сравниваете это с результатом того же действия, но с удаленной тестируемой последовательностью. Конечно, это не учитывает подробностей - как минимум, вам необходимо:

  1. правильно настроить регистры перед каждым CPUID
  2. сохранить значение в EAX: EDX после первого RDTSC
  3. вычесть результат из второго RDTSC из первого

Также обратите внимание на директиву align, которую я вставил - выравнивание инструкций также может повлиять и на синхронизацию, особенно если задействован цикл.

2 голосов
/ 17 апреля 2010

Создайте цикл, который будет выполняться 10 миллионов раз, при этом в теле цикла ничего не будет, и время это. Оставьте это время в качестве накладных расходов, необходимых для зацикливания.

Затем выполните тот же цикл снова, на этот раз с тестируемым кодом в теле. Время для этого цикла, за вычетом накладных расходов (из случая пустого цикла) - это время из-за 10 миллионов повторений тестируемого кода. Итак, разделите на количество итераций.

Очевидно, что этот метод нуждается в настройке с учетом количества итераций. Если то, что вы измеряете, невелико, например, отдельная инструкция, вам может потребоваться выполнить более миллиарда итераций. Если это значительный кусок кода, может быть достаточно нескольких десятков тысяч.

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

Обратите внимание, что на современных конвейерных процессорах параллелизм на уровне команд может запутать ваши результаты. Поскольку в конвейере выполнения одновременно выполняется более одной инструкции, больше не соответствует действительности, что N повторений данной инструкции занимают в N раз больше времени, чем одна.

0 голосов
/ 06 апреля 2012

Хорошо, проблема, с которой вы столкнетесь, если вы используете ОС, такие как Windows, Linux, Unix, MacOS, AmigaOS и все остальные, что на вашем компьютере уже запущено множество процессов в фоновом режиме, что повлияет на спектакль. Единственный реальный способ подсчета фактического времени инструкции - это разобрать вашу материнскую плату и протестировать каждый компонент с использованием внешнего оборудования. Это зависит от того, хотите ли вы сделать это самостоятельно или просто выяснить, насколько быстро работает типичная версия вашего процессора. Такие компании, как Intel и Motorola тщательно тестируют свои чипы перед выпуском, и эти результаты доступны для общественности. Все, что вам нужно сделать, это спросить их, и они отправят вам бесплатный CD-ROM (это может быть DVD - бессмысленная педантичность) с результатами, содержащимися. Вы можете сделать это самостоятельно, но имейте в виду, что особенно процессоры Intel содержат много избыточных инструкций, которые больше не желательны, не говоря уже о необходимости. Это займёт у вас много времени, но я могу видеть, как это весело. PS. Если это просто поможет увеличить аппаратное обеспечение вашей собственной машины до теоретического максимума в личном проекте, который вы выполняете, ответ Джаста Джеффа выше, отлично подходит для генерации аккуратных средних значений скорости выполнения команд в реальных условиях.

0 голосов
/ 17 апреля 2010

Нет, но вы можете рассчитать его на основе количества тактов, которое требуется для инструкции добавления, умноженного на тактовую частоту ЦП. Различные типы аргументов для ADD могут привести к большему или меньшему количеству циклов, но для данного списка аргументов инструкция всегда занимает одинаковое количество циклов.

Тем не менее, почему вы заботитесь?

...