Faster TMultiReadExclusiveWriteSynchronizer?

critical-section, delphi, multithreading, readerwriterlock, readerwriterlockslim

Solution

`TOmniMREW` from `OmniThreadLibrary` claims to be faster and more lightweight:

OTL is an excellent threading lib, BTW.

Sample Code

TOmniReaderWriterLock = class(TInterfacedObject, IReaderWriterLock)
private
   omrewReference: Integer;
public
   { IReaderWriterLock }
   procedure BeginRead;
   procedure EndRead;
   procedure BeginWrite;
   procedure EndWrite;
end;

{ TOmniReaderWriterLock }

procedure TOmniReaderWriterLock.BeginRead;
var
  currentReference: Integer;
begin
    //Wait on writer to reset write flag so Reference.Bit0 must be 0 than increase Reference
    repeat
        currentReference := Integer(omrewReference) and not 1;
    until currentReference = Integer(InterlockedCompareExchange(Pointer(omrewReference), Pointer(Integer(currentReference) + 2), Pointer(currentReference)));
end;

procedure TOmniReaderWriterLock.EndRead;
begin
    //Decrease omrewReference
    InterlockedExchangeAdd(@omrewReference, -2);
end;

procedure TOmniReaderWriterLock.BeginWrite;
var
    currentReference: integer;
begin
    //Wait on writer to reset write flag so omrewReference.Bit0 must be 0 then set omrewReference.Bit0
    repeat
        currentReference := omrewReference and (not 1);
    until currentReference = Integer(InterlockedCompareExchange(Pointer(omrewReference), Pointer(currentReference+1), Pointer(currentReference)));

    //Now wait on all readers
    repeat
    until omrewReference = 1;
end;

procedure TOmniReaderWriterLock.EndWrite;
begin
    omrewReference := 0;
end;

Problem

Is there a faster kind of `TMultiReadExclusiveWriteSynchronizer` out there? FastCode perhaps? Starting with Windows Vista, Microsoft added a Slim Reader/Writer lock. It performs much better than Delphi's `TMultiReadExclusiveWriteSynchronizer`. Unfortunately it only exists in Windows Vista and later, something which few customers actually have yet. Presumably the concepts in use inside a `Slim Reader/Writer lock` could be redone in native Delphi code - but has anyone done it? i have a situation where acquiring and releasing locks on a `TMultiReadExclusiveWriteSynchronizer` (even when there's no contention - a single thread), causes 100% overhead (the operation time doubles). i can run without locking, but then my class is no longer thread-safe. Is there a faster `TMultiReadExclusiveWriteSynchronizer`? Note: If i use a `TCriticalSection` i only suffer a 2% performance hit (although critical sections are known to be fast when the acquire succeeds, i.e. while it's single threaded and there's no contention). The downside of a CS is that i lose the "multiple readers" capability. The Measurements Using `TMultiReadExclusiveWriteSynchronizer` a sizable amount of time is spent inside `BeginRead` and `EndRead`: i then ported the code to use Window's own SlimReaderWriter Lock (which some code rewrite, as it doesn't support recursive lock taking), and profiled the resutls: `TMultiReadExclusiveWriteSynchronizer`: 10,698 ns per iteration 10,697,772,613 ns to iterate 1,000,000 times `SRWLock`: 8,802 ns per iteration 8,801,678,339 ns to iterate 1,000,000 times `Omni Reader-Writer lock`: 8,941 ns per iteration 8,940,552,487 ns to iterate 1,000,000 times A 17% improvement when using SRWLocks (aka Omni's spinning lock). Now, i cannot switch the code permanantly over to use Windows Vista SRWLocks, as there are some entire enterprises of customers that are still on Windows XP. The Slim locks are just careful use of `InterlockedCompareExchange` functions; but more careful than i can successfully use. I'm this far away from just stealing the 140 machine instructions involved, and have it done. Bonus Reading - Is Critical Section always faster? - How to write fast multi-thread Delphi applications

Original source

Related problems