3) Тормозит работу процессора и то, что затрачивается много времени на обмен данными, которые находятся в постоянной памяти. И даже при небольших вычислениях микропроцессор обращается к ОЗУ за данными, а мог бы данные хранить в собственных регистрах
Решение: по возможности, часто используемые данные желательно размещать либо в регистрах процессора, либо в быстрой кэш-памяти. Многие компиляторы не заботятся о том, чтобы разместить данные так, чтобы наблюдалась максимальная скорость работы программы.
4) Так же скорость вычисления уменьшается из-за того, что процессору приходится останавливать свою работу и выполнять аппаратные прерывания. Реакция процессора на прерывания:
а) приходит прерывание;
б) процессор прекращает выполнять основную задачу;
в) происходит сохранение положения, на котором остановилась основная программа;
г) выполняется прерывание;
д) процессор восстанавливает запомненное состояние;
е) продолжает выполнение основной задачи.
Надо заметить, что процессор тратит много времени на сохранение своего текущего состояния и восстановление.
Решение: во время вычисления больших объёмов информации можно запретить некоторые аппаратные прерывания ниже IRQ 0 (таймер). Запрещённые прерывания не будут останавливать процессор, соответственно скорость выполнения возрастёт. Недостатки: могут потеряться некоторые данные, например символы, которые вводятся с клавиатуры – прерывание IRQ 1.
§4. Алгоритм решения
Рассмотрим недостаток № 3. Затрачивание времени на обмен данными.
Блок 1-7. Подсчёт времени на выполнение выбранной операции на языке высокого уровня. В данном случае применяется язык Pascal.
Блок 1. Начало программы.
Блок 2. Вводятся два числа с клавиатуры.
Блок 3. Выбираем операцию из предложенных на экране. Если это операция сложения, то выполняется алгоритм суммирования ряда, если умножение, то выполняется вычисление факториала.
Ввели N, то рад сложения выглядит следующим образом:
1+2+3+…+N=СУММА
Умножения
1*2*3*…*N=ПРОИЗВЕДЕНИЕ
Блок 4. Включаем таймер и запоминаем начальное значение.
Блок 5. Выполняем выбранную операцию на Pascal.
Блок 6. Выключаем таймер и запоминаем считанное значение
Блок 7. Находим разницу между начальным значением времени и конечным
Блок 8-14. Подсчёт времени на выполнение выбранной операции на языке низкого уровня. Применяется язык Assembler.
Блок 8. Переменные, которые мы вводим с клавиатуры, находятся в памяти. Чтобы начать вычисления мы должны из памяти (ОЗУ) поместить значения в регистры процессора. Это мы делаем до включения таймера, чтобы время, затраченное на это действие, не вошло в результат.
Блок 9. Считываем начальное значение времени.
Блок 10. Выполняем операцию
Блок 11. Считываем конечное время
Блок 12. Находим время выполнения операции – это разница между конечным значением и начальным.
Блок 13. Выводим значение времен на экран и делаем выводы.
Блок 14. Выход из программы.
§6. Листинг программы
Program Test_of_CPU_for_Zuev;
uses crt;
var
vid:byte;
t1,t2,NN:word;
time1,time2:real;
Procedure Add_Pascal(N:word); {Сложение на Pascal}
var i:word;
Summa:integer;
Begin
summa:=0;
t1:=0;
t2:=0;
asm
in al,40h
mov bl,al
in al,40h {Считываем начальное значение тиков от таймера}
mov bh,al
mov t1,bx
end;
for i:=1 to N do
summa:=summa+i;
asm
in al,40h
mov bl,al {Конечное количество тиков}
in al,40h
mov bh,al
mov t2,bx
end;
Time1:=t1/(65536*18.2);
time2:=t2/(65536*18.2);
writeln('Время выполнения сложения на Pascal: ',(time2-time1):6:12);
end;
Procedure Add_Asm(N:word);
var i:word;
Proisv:integer;
Begin
t1:=0;
t2:=0;
asm
in al,40h
mov ah,al
in al,40h
xchg ah,al
mov t1,ax
xor ax,ax
xor dx,dx
@@q: {Выполняем сложение}
inc dx
add ax,dx
loop @@q
in al,40h
mov cl,al
in al,40h
mov ch,al
mov t2,cx
end;
Time1:=t1/(65536*18.2);
time2:=t2/(65536*18.2);
writeln('Время выполнения сложения на Assembler: ',(time2-time1):6:12);
end;
{=================================================================}
Procedure Mul_Pascal(N:word); {Умножение на Assembler}
var i:word;
Proisv:integer;
Begin
t1:=0;t2:=0;
asm
in al,40h
mov bl,al
in al,40h {Считываем начальное значение тиков от таймера}
mov bh,al
mov t1,bx
end;
for i:=1 to N do
proisv:=proisv*i;
asm
in al,40h
mov bl,al {Конечное количество тиков}
in al,40h
mov bh,al
mov t2,bx
end;
Time1:=t1/(65536*18.2);
time2:=t2/(65536*18.2);
writeln('Время выполнения умножения на Pascal: ',(time2-time1):6:12);
end;
Procedure Mul_Asm(N:word);
var Proisv:integer;
Begin
t1:=0;
t2:=0;
asm
in al,40h
mov bl,al
in al,40h {Считываем начальное значение тиков от таймера}
mov bh,al
mov t1,bx
xor ax,ax
xor bx,bx
@@q: {Выполняем сложение}
inc dx
mul dx
loop @@q
in al,40h
mov bl,al
in al,40h {Конечное количество тиков}
mov bh,al
mov t2,bx
end;
Time1:=t1/(65536*18.2);
time2:=t2/(65536*18.2);
writeln('Время выполнения умножения на Assembler: ',(time2-time1):6:12);
end;
Begin
clrscr;
{Определяем вид операции}
textcolor(11);
Writeln('Сделайте выбор операции и нажмите клавишу ENTER:');
Writeln('1) Сложение');
Writeln('2) Умножение');
Readln(vid);
textcolor(10);
Case vid of
1: begin
write('Введите сумму ряда, не более 2-х байт (65535: )');
Readln(NN);
Writeln;
textcolor(3);
Add_Pascal(NN);
Add_Asm(NN);
end;
2: begin
write('Введите произведение ряда, не более 2-х байт (65535: )');
Readln(NN);
Writeln;
textcolor(3);
Mul_Pascal(NN);
Mul_Asm(NN);
end;
end;
readln;
End.
Программа написана на алгоритмическом языке Pascal. Состоит из двух блоков. В каждом блоке две процедуры: первая – это выполнение операции на языке Pascal, а вторая – выполнение этой же операции на языке Assembler.
Первый блок.
Состоит из двух процедур, которые выполняют сложение на языке Pascal и Assembler. Производится суммирование ряда чисел. Измерение времени происходит с помощью микросхемы таймера 8253. Сначала считываем начальное число тиков, затем выполняем операцию и снова считываем число с микросхемы. Разница, разделенная на произведение 65535*18,2 и будет временем выполнения операции.
asm
in al,40h
mov bl,al
in al,40h {Считываем начальное значение тиков от таймера}
mov bh,al
mov t1,bx
end;
asm
in al,40h
mov bl,al
in al,40h {Конечное количество тиков}
mov bh,al
mov t2,bx
end;
Time = t2-t1/(65536*18.2); {ВРЕМЯ ВЫПОЛНЕНИЯ ОПЕРАЦИИ}
Второй блок.
Аналогичен первому блоку, с той лишь разницей, что здесь выполняется другая операция – вычисление факториала.
§8. Экспериментальные данные
Для проведения эксперимента вводятся числа:
10;100;1000;5000;10000;15000;20000;25000;30000;35000;50000;60000;65000;
Данные вводятся как для суммирования ряда, так и для вычисления факториала.
Все вычисления выполнялись на микропроцессоре AMD Athlon 1000 MHz
Средняя температура процессора при вычислении 64 °С
Вычисление суммы ряда.
СЛОЖЕНИЕ | ||
Введенное знвчение | Pascal | Assembler |
10 | 1,34143E-05 | 1,84447E-05 |
100 | 1,67679E-05 | 1,34143E-05 |
1000 | 4,19198E-05 | 2,17983E-05 |
5000 | 0,000157618 | 5,19805E-05 |
10000 | 0,000301822 | 9,22234E-05 |
15000 | 0,000444349 | 0,000132466 |
20000 | 0,00059023 | 0,000171033 |
25000 | 0,000734434 | 0,000211276 |
30000 | 0,000875284 | 0,000249842 |
35000 | 0,001021165 | 0,000290085 |
50000 | 0,001483959 | 0,000410814 |
60000 | 0,001742185 | 0,00050136 |
65000 | 0,001884712 | 0,000528189 |
Вычисление факториала.
УМНОЖЕНИЕ | ||
Введенное знвчение | Pascal | Assembler |
10 | 1,50911E-05 | 1,34143E-05 |
100 | 2,85054E-05 | 1,34143E-05 |
1000 | 0,000159295 | 2,51519E-05 |
5000 | 0,000749525 | 7,2102E-05 |
10000 | 0,001482282 | 0,000132466 |
15000 | 0,002216716 | 0,000191154 |
20000 | 0,002994747 | 0,000251519 |
25000 | 0,003687261 | 0,000338712 |
30000 | 0,00443511 | 0,000368894 |
35000 | 0,005157806 | 0,000429258 |
50000 | 0,007403028 | 0,000608675 |
60000 | 0,00887525 | 0,000727727 |
65000 | 0,009579501 | 0,000786415 |