Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КСР.doc
Скачиваний:
6
Добавлен:
24.11.2019
Размер:
117.76 Кб
Скачать

Измерение времени выполнения элементарных операций

Время выполнения различных команд процессора сильно различается.

Пусть у нас имеется циклическая процедура с количеством итераций N. Предположим, что внутри цикла выполняется какая-либо элементарная операция. Тогда, измерив время работы цикла, можно приближенно оценить время выполнения данной операции по формуле: , где T – время выполнения цикла.

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

На пути точного измерения времени выполнения операций имеется целый ряд довольно значительных трудностей:

1. Одна операция компьютера выполняется за незначительную долю секунды: следует ожидать, что современный процессор с частотой 1 ГГц выполняет простейшую команду за время порядка 10-9с. (величина, обратная частоте).

2. Помимо нашей задачи компьютер параллельно выполняет еще несколько, например, очень существенно влияет функционирование операционной системы.

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

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

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

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

Для повышения приоритета необходимо выполнить следующие действия:

  1. Сохранить текущий приоритет задачи;

  2. Установить более высокий приоритет для задачи;

  3. Выполнить необходимые действия;

  4. Установить обратно сохраненный приоритет.

Для сохранения текущего приоритета используются следующие инструкции WinAPI:

PriorityClass := GetPriorityClass(GetCurrentProcess);

Priority := GetThreadPriority(GetCurrentThread);

Переменные PriorityClass и Priority имеют тип integer.

Для установки нового приоритета используются следующие инструкции WinAPI:

SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);

SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);

Здесь мы устанавливаем приоритет выполнения задачи (программы) в значение REALTIME_PRIORITY_CLASS, что означает режим реального времени (максимальный приоритет), и приоритет потока (фактически, нашей процедуры измерения) в значение THREAD_PRIORITY_TIME_CRITICAL – критический по времени приоритет (максимальный).

Для возврата сохраненных приоритетов выполняем инструкции

SetThreadPriority(GetCurrentThread, Priority);

SetPriorityClass(GetCurrentProcess, PriorityClass);

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

С помощью функций WinAPI можно получить количество “тиков” (синхроимпульсов внутреннего таймера), прошедших с момент включения компьютера. Также можно получить количество “тиков” за одну секунду.

Для этого используются следующие функции:

QueryPerformanceFrequency(iCounterPerSec) – в переменной iCounterPerSec возвращает количество “тиков” за одну секунду;

QueryPerformanceCounter(C1) – в переменной C1 возвращает количество “тиков” прошедших с момента включения компьютера.

Переменные iCounterPerSec и C1 имеют тип TLargeInteger.

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

PriorityClass := GetPriorityClass(GetCurrentProcess);

Priority := GetThreadPriority(GetCurrentThread);

QueryPerformanceFrequency(iCounterPerSec);

SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);

SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);

QueryPerformanceCounter(C1);

a := a + 1;

QueryPerformanceCounter(C2);

SetThreadPriority(GetCurrentThread, Priority);

SetPriorityClass(GetCurrentProcess, PriorityClass);

ShowMessage(FormatFloat('0.0000', (C2 - C1) / iCounterPerSec) + ' сек.');

В данной программе измеряется время выполнения одного сложения.

Задание

  1. В среде Delphi создать программу для измерения времени выполнения элементарных операций: сложения, вычитания, умножения целых чисел. Для этого необходимо выполнить операцию в цикле из, например, 1000000000 итераций.

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

  3. В среде Delphi создать программу для измерения времени выполнения операции деления и ее заменой умножением (например, деление на 4 это то же самое, что умножение на 0.25). Для этого необходимо выполнить умножение в цикле из, например, 1000000000 итераций.

  4. Создать таблицу с результатами измерения, полученными в пп.1-3.

  5. Рассчитать тактовую частоту процессора, считая, что операции сложения, вычитания и присваивания выполняется за один такт (“тик”) работы процессора.

  6. По выполненной работе оформить отчет, включая ответы на вопросы.

Контрольные вопросы

  1. Что такое тактовая частота процессора?

  2. От чего зависит скорость выполнения команды?

  3. Что мешает повысить быстродействие процессора за счет увеличения количества конвейеров?

  4. Для чего нужно увеличивать приоритет задачи и потока? Какие функции WinAPI для этого используются?

  5. Какие функции WinAPI используются для работу с “тиками” процессора?

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]