Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Assembler-Multiplikation


Arno-Wien - So 01.01.06 12:14
Titel: Assembler-Multiplikation
Mit Assembler gehts um ca 20% schneller, leider muss x2 real sein (und nicht extended).
Gibt es eine Lösung




Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Button1: TButton;
    Button2: TButton;
    Label5: TLabel;
    Label6: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    procedure ende(Sender: TObject);
    procedure start(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.dfm}


procedure zeit1;
var Hour,Min,Sec,MSec:word;
begin
  DecodeTime(Time,Hour,Min,Sec,MSec);
  form1.label1.caption:='Start: Sec:  '+inttostr(sec)+
    '    MSec: '+inttostr(msec);
end;

procedure zeit2;
var Hour,Min,Sec,MSec:word;
begin
  DecodeTime(Time,Hour,Min,Sec,MSec);
  form1.label2.caption:='Ende: Sec:  '+inttostr(sec)+
    '    MSec:  '+inttostr(msec);
end;

procedure zeit3;
var Hour,Min,Sec,MSec:word;
begin
  DecodeTime(Time,Hour,Min,Sec,MSec);
  form1.label5.caption:='Start: Sec:  '+inttostr(sec)+
    '    MSec:  '+inttostr(msec);
end;

procedure zeit4;
var Hour,Min,Sec,MSec:word;
begin
  DecodeTime(Time,Hour,Min,Sec,MSec);
  form1.label6.caption:='Ende: Sec:  '+inttostr(sec)+
    '    MSec:  '+inttostr(msec);
end;


procedure TForm1.ende(Sender: TObject);
begin
  close
end;


procedure TForm1.start(Sender: TObject);
var i:longint;
    x1,x3:extended;
    x2:real;
    s:string;

procedure mal_compiler;
begin
  x3:=x1*x2;
end;

procedure mal_assembler;
asm
  fld x1
  fmul x2
  fstp x3
end;

begin
  x1:=2.3;
  x2:=3.4;
  x3:=0.0;
  zeit1;
  for i:=0 to 1000000000 do
    mal_compiler;
  zeit2;
  str(x3:5:5,s);
  form1.Label3.Caption:=s;
  zeit3;
  for i:=0 to 1000000000 do
    mal_assembler;
  zeit4;
  str(x3:5:5,s);
  form1.Label4.Caption:=s;
  (*ca. 20 sek bei 3 GHz*)
end;

end.


Arno-Wien


BenBE - So 01.01.06 12:28

Was ist deine Frage? Klar geht's mit ASM schneller ;-)


Born-to-Frag - So 01.01.06 12:34

Ich glaube er sucht nach einer Lösung extended und nicht real zu benutzen ;)


Horst_H - So 01.01.06 13:31

Hallo,

http://ivs.cs.uni-magdeburg.de/bs/lehre/sose99/bs1/nasm/nasmdoca.html nach Fmul suchen

FMUL kann nur 32 und 64 Bit Fliesskommazahlen direkt verarbeiten.
Wenn er es eilig hat, sollte er direkt double nutzen,wie man am Ende des Programmtextes sieht.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
program MulProj;

{$APPTYPE CONSOLE}

uses
  SysUtils;
Const
  RUNDEN = 10000000;
var
  d1,d2,d3 : double;
  x1,x2,x3 : extended;
  t1,t2 : TdateTime;
  i : integer;
procedure mal_compilerExt;
begin
  x3:=x1*x2;
end;
procedure mal_compilerdbl;
begin
  d3:=d1*d2;
end;

procedure mal_assemblerExt;
asm
  fld x1
  fld x2
  fmulp st(1),ST(0)
  fstp x3
end;

procedure mal_assemblerdbl;
asm
  fld d1
  fmul d2
  fstp d3
end;

begin
  x1 := 2-1e-14;
  X2 := 3+1e-14;
  d1 := x1;
  d2 := x2;

  x3 := 0;
  t1 := time;
  for i := 1 to RUNDEN do
     mal_compilerext;
  t1:= t1-time;
  writeln(x3);
  writeln('CompilerExt  '+FormatDateTime('hh:mm:ss.zzz',t1));

  x3 := 0;
  t2 := time;
  for i := 1 to RUNDEN do
     mal_assemblerExt;
  t2 := t2-time;
  writeln(x3);
  writeln('AssemblerExt '+FormatDateTime('hh:mm:ss.zzz',t2));

  d3 := 0;
  t1 := time;
  for i := 1 to RUNDEN do
     mal_compilerdbl;
  t1:= t1-time;
  writeln(d3);
  writeln('CompilerDbl  '+FormatDateTime('hh:mm:ss.zzz',t1));

  d3 := 0;
  t2 := time;
  for i := 1 to RUNDEN do
     mal_assemblerdbl;
  t2 := t2-time;
  writeln(d3);
  writeln('AssemblerDbl '+FormatDateTime('hh:mm:ss.zzz',t2));

  readln;
end.
{
 5.99999999999999E+0000
CompilerExt  00:00:00.240
 5.99999999999999E+0000
AssemblerExt 00:00:00.160
 5.99999999999999E+0000
CompilerDbl  00:00:00.040
 5.99999999999999E+0000
AssemblerDbl 00:00:00.050
}


Gruss Horst