🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.delphi.basm
18 messages
18 total messages Started by Robert Lee Tue, 17 Sep 2002 03:30
deLOCKer Patch
#183
Author: Robert Lee
Date: Tue, 17 Sep 2002 03:30
70 lines
2507 bytes
So here's a first version of the deLOCKer patch.  I'm testing it on
LStrClr and to "should" work on any delphi version.

Comments, Complaints....

unit testpatch;

interface

type
  DWORD = longword;

const
  kernel = 'kernel32.dll';
  PAGE_NOACCESS  = 1;
  PAGE_READWRITE = 4;

type THandle = Integer;

function FlushInstructionCache(hProcess: THandle; const lpBaseAddress:
  Pointer; dwSize: DWORD): BOOL; stdcall;
  external kernel name 'FlushInstructionCache';
function GetCurrentProcess: THandle; stdcall;
  external kernel name 'GetCurrentProcess';
function VirtualProtect(lpAddress:pointer; dwSize, flNewProtect: DWORD;
  var lpflOldProtect:DWord):BOOL; stdcall;
  external kernel name 'VirtualProtect';

implementation

type
  PByteArray=^TByteArray;
  TByteArray=array[0..maxint -1] of byte;
  PDWord=^longword;

const
  NopOp=$90;
  LStrClrLock=$F84AFFF0;

procedure PatchLStrClr;
var
  ProcAddr:PByteArray;
  OldProtect,Protect:DWord;
  i:integer;
begin
  asm  // bunch of fooling around to find start of LStrClr;
    lea eax, System.@LStrClr;
    mov ProcAddr,eax;
  end;
  VirtualProtect(ProcAddr,100,PAGE_READWRITE,OldProtect);
  // make change
  for i:=0 to 99 do
    if ProcAddr[i]=$F0 then // Look
      if PDWord(@ProcAddr[i])^=LStrClrLock then // verify
      begin
        ProcAddr[i]:=NopOp; // change
        break;
      end;
  VirtualProtect(ProcAddr,100,OldProtect,Protect);
  FlushInstructionCache(GetCurrentProcess, ProcAddr,100);
end;

initialization
 PatchLStrClr;
end.


--
Bob Lee
High Performance Delphi - http://www.optimalcode.com/
Re: deLOCKer Patch
#187
Author: Torjei Kvinen
Date: Tue, 17 Sep 2002 11:29
14 lines
1334 bytes
"Robert Lee" <rhlee@optimalcode.com> wrote in message
> So here's a first version of the deLOCKer patch.  I'm testing it on
> LStrClr and to "should" work on any delphi version.
>
> Comments, Complaints....

There is a reason for the LOCK prefix, which is multi thread on multi
processor systems. There aren't many of these systems now, but that
will change with hyper-threading technology.


--
Regards
Torjei Kvinen
Re: deLOCKer Patch
#188
Author: Robert Lee
Date: Tue, 17 Sep 2002 12:38
29 lines
2107 bytes
Torjei Kvinen wrote:

> "Robert Lee" <rhlee@optimalcode.com> wrote in message
> > So here's a first version of the deLOCKer patch.  I'm testing it on
> > LStrClr and to "should" work on any delphi version.
> >
> > Comments, Complaints....
>
> There is a reason for the LOCK prefix,

Well, yes, that is obvious.  The point (as described by Stefan, myself
and others over the last few years) is that you don't always need this
level of protection and there is a substantial performance penalty for
it.  Consequently, the goal is to provide an easy mechanism to turn this
off.  As with any tool it is up to the user to apply it properly.


> There aren't many of these systems now, but that
> will change with hyper-threading technology.

I simply don't buy this.  Real programmers have to make apps
multi-threaded and history has clearly shown that this is the limiting
step.  Certainly, there is no indication that Delphi is about to
introduce a "wizard" that magically converts your single threaded app
into a multi-threaded one.

--
Bob Lee
High Performance Delphi - http://www.optimalcode.com/
Re: deLOCKer Patch
#191
Author: Stefan Hoffmeister
Date: Tue, 17 Sep 2002 14:03
27 lines
1967 bytes
: Robert Lee <rhlee@optimalcode.com> wrote:

>you don't always need this level of protection 

[LOCK prefix to guarantee atomicity for some operations]

>and there is a substantial performance penalty for it.

For a few, older CPUs. My Celeron 433 is affected, a PIII is not, for
instance.

>  Consequently, the goal is to provide an easy mechanism to turn this
>off.  As with any tool it is up to the user to apply it properly.
>
>
>> There aren't many of these systems now, but that
>> will change with hyper-threading technology.
>
>I simply don't buy this.  Real programmers have to make apps
>multi-threaded 

Hyperthreading will help as soon as there are at least two runnable
processes / threads (system-wide). 

As some messages on the Linux kernel mailing list showed recently, the
effects of hyperthreading will depend in part on how well the OS
scheduler distributes the work-load over processors.
Re: deLOCKer Patch
#192
Author: Robert Lee
Date: Tue, 17 Sep 2002 14:44
21 lines
1584 bytes
Stefan Hoffmeister wrote:

> >and there is a substantial performance penalty for it.
>
> For a few, older CPUs. My Celeron 433 is affected, a PIII is not, for
> instance.

Hmm [testing].  So it would seem.  What about Athlon?  Anyone?


>
> Hyperthreading will help as soon as there are at least two runnable
> processes / threads (system-wide).

Right but it is still up to the (Delphi) probrammer to make the app
multithreaded.  That is the weakest link.


--
Bob Lee
High Performance Delphi - http://www.optimalcode.com/
Re: deLOCKer Patch
#3
Author: Stefan Hoffmeister
Date: Tue, 17 Sep 2002 15:31
19 lines
1868 bytes
: Robert Lee <rhlee@optimalcode.com> wrote:

>> Hyperthreading will help as soon as there are at least two runnable
>> processes / threads (system-wide).
>
>Right but it is still up to the (Delphi) probrammer to make the app
>multithreaded.

Not necessarily.

The idea behind hyperthreading is to have two (well, N, but the
hyperthreading hardware available has N=2) distinct execution contexts
run in tandem, on a single CPU.

Whether these execution contexts are part of the same OS process (aka
threads) or whether they are distinct OS processes will probably only
determine how efficient the hyperthreading features can be used (two
threads on a single hyper-thhreaded CPU are probably more efficient than
two distinct processes on the same CPU)
Re: deLOCKer Patch
#2
Author: Eric Grange
Date: Tue, 17 Sep 2002 15:37
20 lines
1613 bytes
Not sure exactly what to test... If it's relevant, I tried with

   for i:=0 to 10000 do begin
      s:='alpha';
      s1:=s;
      s2:=s;
      s3:=s1;
      s:='';
      s3:='';
      s2:='';
      s1:='omega';
   end;

on an Athlon XP 1800+, and there wasn't a microsecond of 
difference with and without patching (1.508 ms all the time
with D6, I checked and the patch code did actually
change the locks to nops).
There wasn't any difference on a slower Duron either.

Eric
Re: deLOCKer Patch
#4
Author: Robert Lee
Date: Tue, 17 Sep 2002 15:54
14 lines
1371 bytes

Eric Grange wrote:

> Not sure exactly what to test... If it's relevant, I tried with

That is exactly what I wanted to test.

OK so the Lock issue is only relevant to PII and lower.


--
Bob Lee
High Performance Delphi - http://www.optimalcode.com/
Re: deLOCKer Patch
#9
Author: Torjei Kvinen
Date: Tue, 17 Sep 2002 18:11
20 lines
1696 bytes
"Robert Lee" <rhlee@optimalcode.com> wrote in message

> The point (as described by Stefan, myself and others over the last
> few years) is that you don't always need this level of protection

That's true, the LOCK prefix is only necessary with multi processors.
On a single processor system it can safely be replaced with NOP.


> Real programmers have to make apps multi-threaded and history has
> clearly shown that this is the limiting step.

There aren't munch gained by running two (or more) threads on a
single processor system, but hyper-threading technology can execute
two (or more) threads simultaneously.


--
Regards
Torjei Kvinen
Re: deLOCKer Patch
#17
Author: Greg E
Date: Wed, 18 Sep 2002 04:21
11 lines
1482 bytes
That is entirely dependent on what those two (or more) threads are doing.  I
have an application that routinely runs 50 or more threads on single
processor systems, and the performance compared to a single threaded app is
astounding  -- orders of magnitude better.

Your blanket statement about thread performance on single processor systems
shows your lack of experience in actual multi-threading situations.


> There aren't munch gained by running two (or more) threads on a
> single processor system,
Re: deLOCKer Patch
#26
Author: Torjei Kvinen
Date: Wed, 18 Sep 2002 15:02
13 lines
1436 bytes
"Greg E" <greg@nowhere.net> wrote in message

> I have an application that routinely runs 50 or more threads on single
> processor systems, and the performance compared to a single threaded app
> is astounding  -- orders of magnitude better.

That doesn't prove anything, except that you have a well functioning
multithread application.


--
Regards
Torjei Kvinen
Re: deLOCKer Patch
#28
Author: Robert Lee
Date: Wed, 18 Sep 2002 16:18
18 lines
1910 bytes
Torjei Kvinen wrote:

> My point is that the LOCK prefix is necessary on multiprocessor
> systems,

The LOCK prefix is necessary on *multithreaded* applications that might
concurrently access the LOCKed data.  It is theoretically possible for a
task swap to occur during a complex op like inc [someaddress].  Thus
multiprocessing is not required but only dramically increases the
possibility of a race condition.  Conversely,  there *has* to be
competition for the data meaning that the application has to be
multithreaded.  You can have all the cool hyperthreading hardware you
want, but if the app isn't multithreaded there will never be a
possibility of a race-condition.

--
Bob Lee
High Performance Delphi - http://www.optimalcode.com/
Re: deLOCKer Patch
#29
Author: Stefan Hoffmeister
Date: Wed, 18 Sep 2002 16:30
18 lines
2048 bytes
: Robert Lee <rhlee@optimalcode.com> wrote:

>It is theoretically possible for a
>task swap to occur during a complex op like inc [someaddress]. 

The LOCK is only present to ascertain atomic operation over the memory
bus on a multi-processor system, where two different execution contexts
can operate on the very same memory region (this implies that the
process needs to have at least two threads to hit this). Basically,
memory access over the bus is serialized at the CPU / bus level, which
is different from the serialization at an OS level.

There is no task swapping (scheduling) involved at the OS level, because
the LOCK only makes a difference whenever the two execution contexts do
execute in parallel (and are not context switched). 

The LOCK is never needed for a single processor system (for the purpose
of this discussion, HT systems with a single CPU are SMP systems).
Re: deLOCKer Patch
#36
Author: Robert Lee
Date: Wed, 18 Sep 2002 22:05
16 lines
1732 bytes
Stefan Hoffmeister wrote:

> : Robert Lee <rhlee@optimalcode.com> wrote:
>
> >It is theoretically possible for a
> >task swap to occur during a complex op like inc [someaddress].
>
> The LOCK is only present to ascertain atomic operation over the memory
> bus on a multi-processor system, where two different execution contexts

I said "theoretically".  Theoretically, an interrupt could be used that
would effectively split the micro ops that make up a complex command.

--
Bob Lee
High Performance Delphi - http://www.optimalcode.com/
Re: deLOCKer Patch
#37
Author: Robert Lee
Date: Wed, 18 Sep 2002 22:07
17 lines
1836 bytes
Torjei Kvinen wrote:

> "Robert Lee" <rhlee@optimalcode.com> wrote in message
>
> > You can have all the cool hyperthreading hardware you
> > want, but if the app isn't multithreaded there will never be a
> > possibility of a race-condition.
>
> True, but multithread applications will become more common, simply
> because they will run faster than single thread.

Ah, but that is precisely what I disagree with.  Making multithreaded
apps is *hard* and is much more of a barrier than the hardware.

--
Bob Lee
High Performance Delphi - http://www.optimalcode.com/
Re: deLOCKer Patch
#38
Author: Stefan Hoffmeister
Date: Wed, 18 Sep 2002 22:17
15 lines
1897 bytes
: Robert Lee <rhlee@optimalcode.com> wrote:

>Theoretically, an interrupt could be used that
>would effectively split the micro ops that make up a complex command.

An interrupt will not have any effect on this because CPUs execute *full
instructions* atomically and in the order they were issued.

What the CPU does behind your back with RISC-y micro ops, or VLIW
composition a la Transmeta, is irrelevant, because the CPU provides the
contract that, regardless of what it does, the correct semantics of the
*full* instruction always hold.

Again, LOCK has nothing to do with micro ops / VLIW / task switching. It
only has to do with the memory bus of the CPU.
Re: deLOCKer Patch
#41
Author: Robert Lee
Date: Wed, 18 Sep 2002 23:24
12 lines
1666 bytes
Stefan Hoffmeister wrote:

> What the CPU does behind your back with RISC-y micro ops, or VLIW
> composition a la Transmeta, is irrelevant, because the CPU provides the
> contract that, regardless of what it does, the correct semantics of the
> *full* instruction always hold.

OK, I wasn't aware of that.

--
Bob Lee
High Performance Delphi - http://www.optimalcode.com/
Re: deLOCKer Patch
#46
Author: Eric Grange
Date: Thu, 19 Sep 2002 07:49
21 lines
2292 bytes
> True, but multithread applications will become more common, simply
> because they will run faster than single thread.

I somewhat disagree, multithreading has a cost, a complexity and a large
arrays of potential cross-locking and data corruption issues. 
Multi-threading can be convenient to work around system latencies, 
more convenient than tuning a single-threaded variant sometimes, 
but the more thread you use, the more time you waste to thread-switching 
and cache inefficiency.
Even if you have multiple CPUs, SMP forbids you to get the most out of them:
with the same core, one 2GHz CPU will always be faster than two 1GHz CPUs.

I agree with Robert, making an efficient multi-threaded app is not for
everybody, it may be simpler when tasks are independant (like serving files
in an HTTP server), but can also get very complex (f.i. in the DataBase 
or File System kernel code that your HTTP server invokes...).

Hyperthreading is a variant of the fast-context-switching 
ideas and concepts that emerged in the 1980s.

Eric
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads