3. Анализ программы линеаризации по методу мнк
3.1 Исходная версия программы
Address |
Line |
Clockticks |
Source |
|
1 |
|
#include <iostream.h> |
|
2 |
|
#include <conio.h> |
|
3 |
|
#include <stdlib.h> |
|
4 |
|
const n=5; |
|
5 |
|
typedef float ary[n]; |
01:0168 |
6 |
|
void linfit1(ary &x,ary &y,ary &y_calc, |
|
7 |
|
float &a,float &b,» |
|
8 |
|
int n) |
|
9 |
|
{ |
|
10 |
|
float sum_x,sum_y,sum_xy,sum_x2, |
|
11 |
|
sum_y2,xi,yi,sxy,sxx,syy; |
01:016E |
12 |
|
sum_x=0.0; |
01:0173 |
13 |
|
sum_y=0.0; |
01:0178 |
14 |
|
sum_xy=0.0; |
01:017D |
15 |
|
sum_x2=0.0; |
01:0182 |
16 |
|
sum_y2=0.0; |
01:0187 |
17 |
0.41% |
for (int j=0;j<1000000;j++) { |
01:018C |
18 |
4.81% |
for (int i=0; i<n;i++) |
01:0199 |
19 |
1.13% |
{xi=x[i]; |
01:01A5 |
20 |
1.74% |
yi=y[i]; |
01:01B1 |
21 |
3.27% |
sum_x=sum_x+xi; |
01:01BA |
22 |
3.17% |
sum_y=sum_y+yi; |
01:01C3 |
23 |
3.10% |
sum_xy=sum_xy+xi*yi; |
01:01CF |
24 |
7.18% |
sum_x2=sum_x2+xi*xi; |
01:01DB |
25 |
3.13% |
sum_y2=sum_y2+yi*yi;} |
01:01F2 |
26 |
5.64% |
sxx=sum_x2-sum_x*sum_x/n; |
01:0203 |
27 |
4.41% |
sxy=sum_xy-sum_x*sum_y/n; |
01:0214 |
28 |
3.70% |
syy=sum_y2-sum_y*sum_y/n; |
01:0225 |
29 |
3.70% |
b=sxy/sxx; |
01:0230 |
30 |
8.43% |
a=((sum_x2*sum_y-sum_x*sum_xy)/n)/sxx; |
01:024B |
31 |
5.11% |
for ( int i=0; i<n;i++) |
01:0258 |
32 |
8.37% |
y_calc[i]=a+b*x[i]; |
01:028F |
33 |
|
}} |
01:0294 |
34 |
|
void main() |
|
35 |
|
{ |
01:029A |
36 |
|
randomize(); |
|
37 |
|
ary x,y,y_calc; |
|
38 |
|
float a,b; |
01:029F |
39 |
|
for ( int i=0;i<n;i++) |
|
40 |
|
{ |
01:02A4 |
41 |
|
x[i]=random(11); |
01:02B9 |
42 |
|
y[i]=random(10); |
01:02CE |
43 |
|
y_calc[i]=0; |
|
44 |
|
} |
01:02E0 |
45 |
|
a=0; b=0; |
01:02EA |
46 |
|
linfit1(x,y,y_calc,a,b,n); |
01:0308 |
47 |
|
} |
|
48 |
|
|
|
49 |
|
|
3.2 Исправленная версия программы
Address |
Line |
Clockticks |
Source |
|
1 |
|
#include <iostream.h> |
|
2 |
|
#include <conio.h> |
|
3 |
|
#include <stdlib.h> |
|
4 |
|
const n=5; |
|
5 |
|
typedef float ary[n]; |
01:0168 |
6 |
|
void linfit1(ary &x,ary &y,ary &y_calc, |
|
7 |
|
float &a,float &b," |
|
8 |
|
int n) |
|
9 |
|
{ |
|
10 |
|
float sum_x,sum_y,sum_xy,sum_x2 |
|
11 |
|
sum_y2,xi,yi,sxy,sxx,syy;" |
01:016E |
12 |
|
sum_x=0.0; |
01:0173 |
13 |
|
sum_y=0.0; |
01:0178 |
14 |
|
sum_xy=0.0; |
01:017D |
15 |
|
sum_x2=0.0; |
01:0182 |
16 |
|
sum_y2=0.0; |
01:0187 |
17 |
0.57% |
for (int j=0;j<1000000;j++) { |
01:018C |
18 |
3.61% |
for (int i=0; i<n;i++) |
01:0199 |
19 |
1.02% |
{xi=x[i]; |
01:01A5 |
20 |
1.02% |
yi=y[i]; |
01:01B1 |
21 |
2.75% |
sum_x=sum_x+xi; |
01:01BA |
22 |
2.44% |
sum_y=sum_y+yi; |
01:01C3 |
23 |
2.87% |
sum_xy=sum_xy+xi*yi; |
01:01CF |
24 |
5.62% |
sum_x2=sum_x2+xi*xi; |
01:01DB |
25 |
2.59% |
sum_y2=sum_y2+yi*yi;} |
01:01F2 |
26 |
5.00% |
sxx=sum_x2-sum_x*sum_x/n; |
01:0203 |
27 |
4.04% |
sxy=sum_xy-sum_x*sum_y/n; |
01:0214 |
28 |
3.85% |
b=sxy/sxx; |
01:021F |
29 |
6.15% |
a=(sum_x2*sum_y-sum_x*sum_xy)/(n*sxx); |
01:023A |
30 |
3.87% |
for ( int i=0; i<n;i++) |
01:0247 |
31 |
6.05% |
y_calc[i]=a+b*x[i]; |
01:027E |
32 |
|
}} |
01:0284 |
33 |
|
void main() |
|
34 |
|
{ |
01:028A |
35 |
|
randomize(); |
|
36 |
|
ary x,y,y_calc; |
|
37 |
|
float a,b; |
01:028F |
38 |
|
for ( int i=0;i<n;i++) |
|
39 |
|
{ |
01:0294 |
40 |
|
x[i]=random(11); |
01:02A9 |
41 |
|
y[i]=random(10); |
01:02BE |
42 |
|
y_calc[i]=0; |
|
43 |
|
} |
01:02D0 |
44 |
|
a=0; b=0; |
01:02DA |
45 |
|
linfit1(x,y,y_calc,a,b,n); |
01:02F8 |
46 |
|
} |
|
47 |
|
|
|
48 |
|
|
В первом случае суммарное время равно 67.30%. Во втором – 51.45%
Вывод:
Программа test_cyc.c показала, что Vtuneодинаково обрабатывает записанные разными способами последовательности команд например:
for(i=0;i<Size/10;i++){ tmp=dim[0]; dim[0]=dim[i]; dim[i]=tmp; }; 1,76%
и
for(i=0;i<Size/10;i++) |
{ tmp=dim[0]; dim[0]=dim[i]; dim[i]=tmp; }; 1,76% |
Для анализа программы линеаризации по методу МНК пришлось ввести вспомогательное зацикливание.
Улучшить программу линеаризации удалось за счет удаления неиспользуемой переменной: syy=sum_y2-sum_y*sum_y/n; и за счет замены деления умножением:
a=((sum_x2*sum_y-sum_x*sum_xy)/n)/sxx a=(sum_x2*sum_y-sum_x*sum_xy)/(n*sxx);