Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторная работа №12

.doc
Скачиваний:
26
Добавлен:
01.05.2014
Размер:
150.02 Кб
Скачать

Задание

Для заданного варианта программы обработки данных, представленной на языке Паскаль, разработать вычислительный алгоритм и варианты программ его реализации на языках программи-рования Си и Ассемблер. Добиться, чтобы программы на Паскале и Си были работоспособны и давали корректные результаты (это потребуется в дальнейшем при проведении с ними измерительных экспериментов). Для получения ассемблерного представления программы можно либо самостоятельно написать код на ассемблере, реализующий заданный алгоритм, либо установить опцию "Code generation/Generate assembler source" при компиляции текста программы, представленной на языке Си. При этом в ассемблерном представлении программы нужно удалить директивы описаний и отладочные директивы, оставив только исполняемые операторы.

Примечание!

******************************************************************

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

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

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

******************************************************************

Для каждой из разработанных программ (включая исходную программу на Паскале) определить следующие метрические характеристики (по Холстеду):

1. Измеримые характеристики программ:

- число простых(отдельных)операторов, в данной реализации;

- число простых (отдельных) операндов, в данной реализации;

- общее число всех операторов в данной реализации;

- общее число всех операндов в данной реализации;

- число вхождений j-го оператора в тексте программы;

- число вхождений j-го операнда в тексте программы;

- словарь программы;

- длину программы.

2. Расчетные характеристики программы:

- длину программы;

- реальный, потенциальный и граничный объемы программы;

- уровень программы;

- интеллектуальное содержание программы;

- работа программиста;

- время программирования;

- уровень используемого языка программирования;

  • ожидаемое число ошибок в программе.

Для каждой характеристики следует рассчитать как саму характеристику, так и ее оценку.

Расчет оценок программ выполнить двумя способами:

1) вручную или с помощью одного из доступных пакетов математических вычислений DERIVE, MATHCAD или MATLAB.

2) с помощью программы автоматизации расчета метрик Холстеда, краткая инструкция по работе с которой приведена в файле usage.rtf (для С- и Паскаль-версий программ).

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

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

Реализация

Программа 22. Интегрирование методом Симпсона

На Паскале

program plab;

const tol = 1.0E-4;

var sum,upper,lower,

erf,twopi : real;

function fx(x: real): real;

begin

fx:=exp(-x*x)

end;

procedure simps(lower,upper,tol : real; var sum : real);

var i : integer;

x,delta_x,even_sum,

odd_sum,end_sum,

sum1 : real;

pieces : integer;

begin

pieces:=2;

delta_x:=(upper-lower)/pieces;

odd_sum:=fx(lower+delta_x);

even_sum:=0.0;

end_sum:=fx(lower)+fx(upper);

sum:=(end_sum+4.0*odd_sum)*delta_x/3.0;

repeat

pieces:=pieces*2;

sum1:=sum;

delta_x:=(upper-lower)/pieces;

even_sum:=even_sum+odd_sum;

odd_sum:=0.0;

for i:=1 to pieces div 2 do

begin

x:=lower+delta_x*(2.0*i-1.0);

odd_sum:=odd_sum+fx(x)

end;

sum:=(end_sum+4.0*odd_sum+2.0*even_sum)*delta_x/3.0;

until abs(sum-sum1)<=abs(tol*sum1)

end;

begin

twopi:=2.0/sqrt(pi);

lower:=0.0;

upper:=1;

if upper<0.0 then

begin

simps(lower,upper,tol,sum);

erf:=twopi*sum;

end

end.

Statistics for module plab.lxm

=====================================

The number of different operators : 19

The number of different operands : 25

The total number of operators : 87

The total number of operands : 98

Dictionary ( D) : 44

Length ( N) : 185

Length estimation ( ^N) : 196.807

Volume ( V) : 1009.99

Potential volume ( *V) : 15.5098

Limit volume (**V) : 25.8496

Programming level ( L) : 0.0153563

Programming level estimation ( ^L) : 0.0268528

Intellect ( I) : 27.1212

Time of programming ( T) : 3653.93

Time estimation ( ^T) : 2222.93

Programming language level (lambda) : 0.238173

Work on programming ( E) : 65770.8

Error ( B) : 0.543126

Error estimation ( ^B) : 0.336665

Table:

====================================

Operators:

| 1 | 18 | ()

| 2 | 11 | *

| 3 | 8 | +

| 4 | 5 | -

| 5 | 6 | /

| 6 | 1 | <

| 7 | 1 | <=

| 8 | 20 | =

| 9 | 2 | abs

| 10 | 1 | const

| 11 | 1 | exp

| 12 | 1 | for

| 13 | 5 | fx

| 14 | 1 | if

| 15 | 1 | program

| 16 | 1 | real

| 17 | 1 | repeat

| 18 | 2 | simps

| 19 | 1 | sqrt

Operands:

| 1 | 4 | 0.0

| 2 | 2 | 1

| 3 | 1 | 1.0

| 4 | 1 | 1.0E-4

| 5 | 3 | 2

| 6 | 3 | 2.0

| 7 | 2 | 3.0

| 8 | 2 | 4.0

| 9 | 7 | delta_x

| 10 | 4 | end_sum

| 11 | 2 | erf

| 12 | 5 | even_sum

| 13 | 1 | fx

| 14 | 2 | i

| 15 | 9 | lower

| 16 | 8 | odd_sum

| 17 | 1 | pi

| 18 | 7 | pieces

| 19 | 1 | plab

| 20 | 8 | sum

| 21 | 4 | sum1

| 22 | 4 | tol

| 23 | 3 | twopi

| 24 | 8 | upper

| 25 | 6 | x

На С++

const double tol = 1.0E-4;

double sum, upper, lower, erf, twopi;

double fx(double x)

{

return exp(-x * x);

}

double simps(double lower,double upper,double tol)

{

int i;

double x,delta_x,even_sum,odd_sum,end_sum, sum1;

int pieces;

double sum;

pieces = 2;

delta_x = (upper - lower) / pieces;

odd_sum = fx(lower + delta_x);

even_sum = 0.0;

end_sum = fx(lower) + fx(upper);

sum = (end_sum + 4.0 * odd_sum) * delta_x / 3.0;

do

{

pieces = pieces * 2;

sum1 = sum;

delta_x = (upper - lower) / pieces;

even_sum = even_sum + odd_sum;

odd_sum = 0.0;

for (i = 1; i <= (pieces / 2); i++)

{

x = lower + delta_x * (2.0 * i - 1.0);

odd_sum = odd_sum + fx(x);

}

sum = (end_sum + 4.0 * odd_sum + 2.0 * even_sum) * delta_x / 3.0;

}

while (abs(sum - sum1) > abs(tol * sum1));

return sum;

}

void main ()

{

double res;

double pi = 3.14159265359;

done = false;

twopi = 2.0 / sqrt(pi);

lower = 0.0;

upper = 1;

if (upper >= 0.0)

{

res = simps(lower,upper,tol);

erf = twopi * res;

}

}

Statistics for module labmet.lxm

=====================================

The number of different operators : 22

The number of different operands : 27

The total number of operators : 99

The total number of operands : 105

Dictionary ( D) : 49

Length ( N) : 204

Length estimation ( ^N) : 226.489

Volume ( V) : 1145.4

Potential volume ( *V) : 15.5098

Limit volume (**V) : 25.8496

Programming level ( L) : 0.0135409

Programming level estimation ( ^L) : 0.0233766

Intellect ( I) : 26.7756

Time of programming ( T) : 4699.34

Time estimation ( ^T) : 3022.18

Programming language level (lambda) : 0.210017

Work on programming ( E) : 84588.1

Error ( B) : 0.64232

Error estimation ( ^B) : 0.3818

Table:

====================================

Operators:

| 1 | 12 | ()

| 2 | 11 | *

| 3 | 8 | +

| 4 | 1 | ++

| 5 | 13 | ,

| 6 | 4 | -

| 7 | 6 | /

| 8 | 1 | <=

| 9 | 23 | =

| 10 | 1 | >

| 11 | 1 | >=

| 12 | 1 | _-

| 13 | 2 | abs

| 14 | 1 | dowhile

| 15 | 1 | exp

| 16 | 1 | for

| 17 | 5 | fx

| 18 | 1 | if

| 19 | 1 | main

| 20 | 2 | return

| 21 | 2 | simps

| 22 | 1 | sqrt

Operands:

| 1 | 4 | 0.0

| 2 | 2 | 1

| 3 | 1 | 1.0

| 4 | 1 | 1.0E-4

| 5 | 3 | 2

| 6 | 3 | 2.0

| 7 | 2 | 3.0

| 8 | 1 | 3.14159265359

| 9 | 2 | 4.0

| 10 | 7 | delta_x

| 11 | 1 | done

| 12 | 4 | end_sum

| 13 | 2 | erf

| 14 | 5 | even_sum

| 15 | 1 | false

| 16 | 5 | i

| 17 | 9 | lower

| 18 | 8 | odd_sum

| 19 | 2 | pi

| 20 | 7 | pieces

| 21 | 3 | res

| 22 | 7 | sum

| 23 | 4 | sum1

| 24 | 4 | tol

| 25 | 3 | twopi

| 26 | 8 | upper

| 27 | 6 | x

С помощью MS Visual C++ был сгенерирован код

На Ассемблере

?fx@@YANN@Z PROC NEAR

push ebp

mov ebp, esp

sub esp, 64

push ebx

push esi

push edi

lea edi, DWORD PTR [ebp-64]

mov ecx, 16

mov eax, -858993460

rep stosd

fld QWORD PTR _x$[ebp]

fchs

fmul QWORD PTR _x$[ebp]

sub esp, 8

fstp QWORD PTR [esp]

call _exp

add esp, 8

pop edi

pop esi

pop ebx

add esp, 64

cmp ebp, esp

call __chkesp

mov esp, ebp

pop ebp

ret 0

?fx@@YANN@Z ENDP

?simps@@YANNNN@Z PROC NEAR

push ebp

mov ebp, esp

sub esp, 136

push ebx

push esi

push edi

lea edi, DWORD PTR [ebp-136]

mov ecx, 34

mov eax, -858993460

rep stosd

mov DWORD PTR _pieces$[ebp], 2

fld QWORD PTR _upper$[ebp]

fsub QWORD PTR _lower$[ebp]

fidiv DWORD PTR _pieces$[ebp]

fstp QWORD PTR _delta_x$[ebp]

fld QWORD PTR _lower$[ebp]

fadd QWORD PTR _delta_x$[ebp]

sub esp, 8

fstp QWORD PTR [esp]

call ?fx@@YANN@Z

add esp, 8

fstp QWORD PTR _odd_sum$[ebp]

mov DWORD PTR _even_sum$[ebp], 0

mov DWORD PTR _even_sum$[ebp+4], 0

mov eax, DWORD PTR _lower$[ebp+4]

push eax

mov ecx, DWORD PTR _lower$[ebp]

push ecx

call ?fx@@YANN@Z

fstp QWORD PTR -72+[ebp]

add esp, 8

mov edx, DWORD PTR _upper$[ebp+4]

push edx

mov eax, DWORD PTR _upper$[ebp]

push eax

call ?fx@@YANN@Z

add esp, 8

fadd QWORD PTR -72+[ebp]

fstp QWORD PTR _end_sum$[ebp]

fld QWORD PTR __real@8@40018000000000000000

fmul QWORD PTR _odd_sum$[ebp]

fadd QWORD PTR _end_sum$[ebp]

fmul QWORD PTR _delta_x$[ebp]

fdiv QWORD PTR __real@8@4000c000000000000000

fstp QWORD PTR _sum$[ebp]

mov ecx, DWORD PTR _pieces$[ebp]

push ecx

push OFFSET FLAT:??_C@_02MECO@?$CFd?$AA@

call _printf

add esp, 8

mov edx, DWORD PTR _sum$[ebp+4]

push edx

mov eax, DWORD PTR _sum$[ebp]

push eax

push OFFSET FLAT:??_C@_02JBAA@?$CFf?$AA@

call _printf

add esp, 12

$L2033:

mov ecx, DWORD PTR _pieces$[ebp]

shl ecx, 1

mov DWORD PTR _pieces$[ebp], ecx

mov edx, DWORD PTR _sum$[ebp]

mov DWORD PTR _sum1$[ebp], edx

mov eax, DWORD PTR _sum$[ebp+4]

mov DWORD PTR _sum1$[ebp+4], eax

fld QWORD PTR _upper$[ebp]

fsub QWORD PTR _lower$[ebp]

fidiv DWORD PTR _pieces$[ebp]

fstp QWORD PTR _delta_x$[ebp]

fld QWORD PTR _even_sum$[ebp]

fadd QWORD PTR _odd_sum$[ebp]

fstp QWORD PTR _even_sum$[ebp]

mov DWORD PTR _odd_sum$[ebp], 0

mov DWORD PTR _odd_sum$[ebp+4], 0

mov DWORD PTR _i$[ebp], 1

jmp SHORT $L2036

$L2037:

mov ecx, DWORD PTR _i$[ebp]

add ecx, 1

mov DWORD PTR _i$[ebp], ecx

$L2036:

mov eax, DWORD PTR _pieces$[ebp]

cdq

sub eax, edx

sar eax, 1

cmp DWORD PTR _i$[ebp], eax

jg SHORT $L2038

fild DWORD PTR _i$[ebp]

fadd ST(0), ST(0)

fsub QWORD PTR __real@8@3fff8000000000000000

fmul QWORD PTR _delta_x$[ebp]

fadd QWORD PTR _lower$[ebp]

fstp QWORD PTR _x$[ebp]

mov edx, DWORD PTR _x$[ebp+4]

push edx

mov eax, DWORD PTR _x$[ebp]

push eax

call ?fx@@YANN@Z

add esp, 8

fadd QWORD PTR _odd_sum$[ebp]

fstp QWORD PTR _odd_sum$[ebp]

jmp SHORT $L2037

$L2038:

fld QWORD PTR __real@8@40018000000000000000

fmul QWORD PTR _odd_sum$[ebp]

fadd QWORD PTR _end_sum$[ebp]

fld QWORD PTR __real@8@40008000000000000000

fmul QWORD PTR _even_sum$[ebp]

faddp ST(1), ST(0)

fmul QWORD PTR _delta_x$[ebp]

fdiv QWORD PTR __real@8@4000c000000000000000

fstp QWORD PTR _sum$[ebp]

fld QWORD PTR _sum$[ebp]

fsub QWORD PTR _sum1$[ebp]

call __ftol

push eax

call _abs

add esp, 4

mov esi, eax

fld QWORD PTR _tol$[ebp]

fmul QWORD PTR _sum1$[ebp]

call __ftol

push eax

call _abs

add esp, 4

cmp esi, eax

jg $L2033

fld QWORD PTR _sum$[ebp]

pop edi

pop esi

pop ebx

add esp, 136

cmp ebp, esp

call __chkesp

mov esp, ebp

pop ebp

ret 0

?simps@@YANNNN@Z ENDP

_main PROC NEAR

push ebp

mov ebp, esp

sub esp, 80

push ebx

push esi

push edi

lea edi, DWORD PTR [ebp-80]

mov ecx, 20

mov eax, -858993460

rep stosd

mov DWORD PTR _pi$[ebp], 1413754602

mov DWORD PTR _pi$[ebp+4], 1074340347

mov BYTE PTR ?done@@3_NA, 0

mov eax, DWORD PTR _pi$[ebp+4]

push eax

mov ecx, DWORD PTR _pi$[ebp]

push ecx

call _sqrt

add esp, 8

fdivr QWORD PTR __real@8@40008000000000000000

fstp QWORD PTR ?twopi@@3NA

mov DWORD PTR ?lower@@3NA, 0

mov DWORD PTR ?lower@@3NA+4, 0

$L2043:

push OFFSET FLAT:?upper@@3NA

mov ecx, OFFSET FLAT:?cin@@3Vistream_withassign@@A

call ??5istream@@QAEAAV0@AAN@Z

fld QWORD PTR ?upper@@3NA

fcomp QWORD PTR __real@8@00000000000000000000

fnstsw ax

test ah, 1

je SHORT $L2046

mov BYTE PTR ?done@@3_NA, 1

jmp SHORT $L2047

$L2046:

mov edx, DWORD PTR _tol+4

push edx

mov eax, DWORD PTR _tol

push eax

mov ecx, DWORD PTR ?upper@@3NA+4

push ecx

mov edx, DWORD PTR ?upper@@3NA

push edx

mov eax, DWORD PTR ?lower@@3NA+4

push eax

mov ecx, DWORD PTR ?lower@@3NA

push ecx

call ?simps@@YANNNN@Z

add esp, 24

fstp QWORD PTR _res$[ebp]

fld QWORD PTR ?twopi@@3NA

fmul QWORD PTR _res$[ebp]

fstp QWORD PTR ?erf@@3NA

mov edx, DWORD PTR ?upper@@3NA+4

push edx

mov eax, DWORD PTR ?upper@@3NA

push eax

push OFFSET FLAT:??_C@_02JBAA@?$CFf?$AA@

call _printf

add esp, 12

mov ecx, DWORD PTR ?erf@@3NA+4

push ecx

mov edx, DWORD PTR ?erf@@3NA

push edx

push OFFSET FLAT:??_C@_03FBAH@?$CFf?6?$AA@

call _printf

add esp, 12

$L2047:

xor eax, eax

mov al, BYTE PTR ?done@@3_NA

test eax, eax

je $L2043

pop edi

pop esi

pop ebx

add esp, 80

cmp ebp, esp

call __chkesp

mov esp, ebp

pop ebp

ret 0

_main ENDP

Расчет метрик Холстеда производился вручную.

Число уникальных операторов (n1):

Число уникальных операндов (n2):

Общее число операторов (N1):

Общее число операндов (N2):

Алфавит (n): n1+n2

Экспериментальна длина программы (Nэ): N1+N2

Теоретическая длина программы (Nт): n1∙log2(n1) + n2∙log2(n2)

Объём программы (V): Nэ∙log2(n)

Потенциальный объём (V*): (N1*+N2*)∙log2(n1* + n2*) = 15,5098

Уровень программы (L): V* / V (от 0 до 1)

Сложность программы (S): L-1

Ожидание уровня программы (L^): (2/n1)∙(n2/N2)

Интеллект программы (I): L^ ∙ V

Работа по программированию (Е): V∙S ≡ V/L

Время кодирования (T): E/St (St – число Страуда от 5 до 20, берем 10)

Ожидаемое время кодирования (T^): n1∙N2 ∙ N∙log2(n) / (2∙St∙n2)

Уровень языка программирования (Lam): (V*)∙(V*)/V

Уровень ошибок (В): V / 3000

Число уникальных операторов (n1):

41

Число уникальных операндов (n2):

61

Общее число операторов (N1):

229

Общее число операндов (N2):

272

Алфавит (n):

102,0000

Экспериментальна длина программы (Nэ):

501,0000

Теоретическая длина программы (Nт):

581,4346

Объём программы (V):

3342,8851

Потенциальный объём (V*):

15,5098

Уровень программы (L):

0,0046

Сложность программы (S):

215,5337

Ожидание уровня программы (L^):

0,0109

Интеллект программы (I):

36,5703

Работа по программированию (Е):

720504,5047

Время кодирования (T):

72050,4505

Ожидаемое время кодирования (T^):

30557,2579

Уровень языка программирования (Lam):

0,0720

Уровень ошибок (В):

1,1143

Table:

====================================

Operators:

| 1

40

| push

| 2

57

| mov

| 3

6

| sub

| 4

3

| lea

| 5

3

| rep

| 6

13

| fld

| 7

1

| fchs

| 8

9

| fmul

| 9

15

| fstp

| 10

17

| add

| 11

5

| cmp

| 12

12

| pop

| 13

3

| ret

| 14

4

| fsub

| 15

2

| fidiv

| 16

2

| fdiv

| 17

1

| shl

| 18

1

| cdq

| 19

1

| sar

| 20

1

| fild

| 21

1

| faddp

| 22

1

| fdivr

| 23

2

| fnstsw

| 24

2

| test

| 25

1

| xor

| 26

1

| call _exp

| 27

3

| call __chkesp

| 28

4

| call ?fx@@YANN@Z

| 29

4

| call _printf

| 30

2

| call _ftol

| 31

2

| call _abs

| 32

1

| call _sqrt

| 33

1

| call ??5istream@@QAEAAV0@AAN@Z

| 34

1

| call ?simps@@YANNNN@Z

| 35

1

| jmp SHORT $L2036

| 36

1

| jmp SHORT $L2037

| 37

1

| jmp SHORT $L2047

| 38

1

| jg SHORT $L2033

| 39

1

| jg SHORT $L2038

| 40

1

| je SHORT $L2043

| 41

1

| je SHORT $L2046

Operands:

| 1

15

| ebp

| 2

32

| esp

| 3

6

| ebx

| 4

8

| esi

| 5

9

| edi

| 6

22

| ecx

| 7

33

| eax

| 8

3

| ST(0)

| 9

1

| ST(1)

| 10

1

| ax

| 11

1

| ah

| 12

17

| edx

| 13

1

| al

| 14

2

| 64

| 15

1

| 16

| 16

3

| -858993460

| 17

8

| 8

| 18

10

| 0

| 19

2

| 136

| 20

1

| 34

| 21

1

| 2

| 22

2

| -72

| 23

2

| 4

| 24

3

| 12

| 25

6

| 1

| 26

2

| 80

| 27

1

| 20

| 28

1

| 14

| 29

3

QWORD PTR _x$[ebp]

| 30

1

DWORD PTR [ebp-64]

| 31

2

QWORD PTR [esp]

| 32

1

DWORD PTR [ebp-136]

| 33

7

DWORD PTR _pieces$[ebp]

| 34

2

QWORD PTR _upper$[ebp]

| 35

4

QWORD PTR _lower$[ebp]

| 36

6

QWORD PTR _delta_x$[ebp]

| 37

6

QWORD PTR _odd_sum$[ebp]

| 38

1

DWORD PTR _even_sum$[ebp],

| 39

1

DWORD PTR _even_sum$[ebp+4],

| 40

1

DWORD PTR _lower$[ebp+4]

| 41

2

QWORD PTR -72+[ebp]

| 42

1

DWORD PTR _upper$[ebp+4]

| 43

3

QWORD PTR _end_sum$[ebp]

| 44

4

QWORD PTR _sum$[ebp]

| 45

2

DWORD PTR _sum$[ebp+4]

| 46

1

DWORD PTR _sum1$[ebp+4]

| 47

3

QWORD PTR _even_sum$[ebp]

| 48

1

DWORD PTR _odd_sum$[ebp],

| 49

1

DWORD PTR _odd_sum$[ebp+4]

| 50

5

DWORD PTR _i$[ebp]

| 51

1

DWORD PTR _x$[ebp+4]

| 52

1

DWORD PTR _x$[ebp]

| 53

6

QWORD PTR _odd_sum$[ebp]

| 54

2

QWORD PTR _sum1$[ebp]

| 55

1

QWORD PTR _tol$[ebp]

| 56

1

DWORD PTR [ebp-80]

| 57

2

DWORD PTR _pi$[ebp]

| 58

1

1,074E+09

| 59

2

DWORD PTR _pi$[ebp+4]

| 60

2

QWORD PTR _res$[ebp]