uses Windows, SyncObjs;
type
TInteger =
record
private
Value: Integer;
public
procedure Add(i: Integer);
end;
TLockedInteger =
record
private
Value: Integer;
public
procedure Add(i: Integer);
end;
TInterlockedInteger =
record
private
Value: Integer;
public
procedure Add(i: Integer);
end;
TRTLCriticalSectionInteger =
record
private
Value: Integer;
Lock: TRTLCriticalSection;
public
procedure Init;
procedure Finalize;
procedure Add(i: Integer);
end;
TCriticalSectionInteger =
record
private
Value: Integer;
Lock: TCriticalSection;
public
procedure Init;
procedure Finalize;
procedure Add(i: Integer);
end;
procedure TInteger.Add(i: Integer);
begin
Inc(Value, i);
end;
procedure TLockedInteger.Add(i: Integer);
asm
lock add [eax], edx
end;
procedure TInterlockedInteger.Add(i: Integer);
begin
InterlockedExchangeAdd(Value, i);
end;
procedure TRTLCriticalSectionInteger.Init;
begin
InitializeCriticalSection(Lock);
end;
procedure TRTLCriticalSectionInteger.Finalize;
begin
DeleteCriticalSection(Lock);
end;
procedure TRTLCriticalSectionInteger.Add(i: Integer);
begin
EnterCriticalSection(Lock);
try
Inc(Value, i);
finally
LeaveCriticalSection(Lock);
end;
end;
procedure TCriticalSectionInteger.Init;
begin
Lock := TCriticalSection.Create;
end;
procedure TCriticalSectionInteger.Finalize;
begin
Lock.Free;
end;
procedure TCriticalSectionInteger.Add(i: Integer);
begin
Lock.Enter;
try
Inc(Value, i);
finally
Lock.Leave;
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
var C: LongWord;
L, k: Integer;
I: TInteger;
LI: TLockedInteger;
II: TInterlockedInteger;
RCSI: TRTLCriticalSectionInteger;
CSI: TCriticalSectionInteger;
begin
// cpu spin up
for L := 0
to 100000000
do
I.Add(10);
C := GetTickCount;
for L := 0
to 30000000
do
I.Add(10);
C := GetTickCount - C;
Memo1.Lines.Add(IntToStr(C));
C := GetTickCount;
for L := 0
to 30000000
do
LI.Add(10);
C := GetTickCount - C;
Memo1.Lines.Add(IntToStr(C));
C := GetTickCount;
for L := 0
to 30000000
do
II.Add(10);
C := GetTickCount - C;
Memo1.Lines.Add(IntToStr(C));
C := GetTickCount;
RCSI.Init;
Try
for L := 0
to 30000000
do
RCSI.Add(10);
Finally
RCSI.Finalize;
End;
C := GetTickCount - C;
Memo1.Lines.Add(IntToStr(C));
C := GetTickCount;
CSI.Init;
Try
for L := 0
to 30000000
do
CSI.Add(10);
Finally
CSI.Finalize;
End;
C := GetTickCount - C;
Memo1.Lines.Add(IntToStr(C));
end;