Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen (https://www.delphipraxis.net/194746-atomictypes-atomare-boolean-integer-enum-und-set-typen.html)

Zacherl 31. Dez 2017 16:20


AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

in C++ gibt es den
Delphi-Quellcode:
std::atomic<T>
Typ, welcher mittels
Delphi-Quellcode:
LOCK CXHG
,
Delphi-Quellcode:
LOCK INC
,
Delphi-Quellcode:
LOCK DEC
, etc. intrinsische atomare Operationen implementiert. Hierbei werden die Operatoren so überladen, dass sich Variablen dieses Typs ganz genau wie der generische Grundtyp verwenden lassen.

Leider sind in Delphi sowohl die
Delphi-Quellcode:
class operators
, als auch die Generics im Vergleich zu C++ stark beschränkt, aber ich habe mich dennoch mal daran versucht entsprechende Typen nachzubilden. Statt einigen 100 Zeilen wurden hieraus dann leider mehrere 1000 Zeilen mit viel repetitivem Code. Zudem gibt es eine recht große Limitierung, bedingt dadurch, dass Delphi das Überladen des Assignment Operators nicht unterstützt. Neue Werte können nicht einfach zugewiesen werden, sondern müssen mit
Delphi-Quellcode:
.Assign
gesetzt werden.

Beispiel:
Delphi-Quellcode:
var
  I, J: TAtomicInt32;
  V: Integer;
  D: Double;
begin
  // Atomic writes
  I.Assign(42);        // I = 42
  J.Assign(24);        // J = 24
  V := J.Exchange(-1); // V = 24, J = -1
  J.Inc;               // J = 0
  J.Sub(1);            // J = -1

  // We can use the atomic type just like a "normal" integer
  V := I + J;          // V = 41
  D := I / 4;          // D = 10.5

  // DON'T DO THIS! Not atomic!
  I := J;
Wer Interesse hat, kann ja mal reinschauen :stupid:
Aktuellste Version auch immer auf GitHub.

Viele Grüße
Zacherl

LTE5 31. Dez 2017 16:45

AW: AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
OT: Embarcadero sollte dich und Andreas Hausladen definitiv unter Vertrag nehmen. Ihr beiden würdet Delphi zu etwas machen, was es bis heute leider nicht ist.

Uwe Raabe 31. Dez 2017 17:13

AW: AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
Kannst du das Assign nicht einfach mit einem Implicit-Operator implementieren?
Delphi-Quellcode:
class operator TAtomicInteger<T>.Implicit(A: T): TAtomicInteger<T>;
begin
  Result.Assign(A);
end;
Edit: Besser gleich mit dem generischen Typ.

Zacherl 31. Dez 2017 17:16

AW: AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1389979)
Kannst du das Assign nicht einfach mit einem Implicit-Operator implementieren?
Delphi-Quellcode:
class operator TAtomicInteger<T>.Implicit(A: Integer): TAtomicInteger<T>;
begin
  Result.Assign(A);
end;

Leider nein. Das Problem hierbei ist, dass Delphi beim Zuweisen eine neue temporäre RValue erstellt. Result liegt praktisch an einer komplett neuen Adresse auf dem Stack - würde dann zwar atomar zugewiesen (was natürlich sinnlos ist) - und dann nicht atomar der vorhandenen LValue zugewiesen.

LTE5 31. Dez 2017 17:29

AW: AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
Für Idioten wie mich erklärt: was bringen diese atomaren ... Dinger?

Zacherl 31. Dez 2017 17:59

AW: AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
Zitat:

Zitat von LTE5 (Beitrag 1389984)
Für Idioten wie mich erklärt: was bringen diese atomaren ... Dinger?

Wenn mehrere Threads auf die gleiche Variable zugreifen, musst du konkurrierende Zugriffe normalerweise ja per
Delphi-Quellcode:
TCriticalSection
,
Delphi-Quellcode:
TMonitor
, etc. absichern. Diese Locks sind von der Performance her nicht wirklich gut, da sie entweder Spin-Locken oder einen Context-Switch in den Kernel bewirken. Die atomaren Typen werden ohne zusätzlichen (Software-)Overhead direkt von der CPU synchronisiert und sind deshalb besonders performant. Allerdings hat dieser Mechanismus auch seine Grenzen, wie dass er z.b. nur für triviale Typen bis maximal 8-Byte anwendbar ist.

LTE5 31. Dez 2017 18:01

AW: AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
Sehr schade. Wäre super schön gewesen, wenn man diese Funktionalität ohne Assign und für komplexere Datentypen hätte.
Vielleicht ließt Emba das ja mit und stellt dich für diese Aufgabe [Ironie an]für Delphi 19.1[/Ironie aus] ein ;)

Zacherl 31. Dez 2017 18:22

AW: AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
Zitat:

Zitat von LTE5 (Beitrag 1389994)
Sehr schade. Wäre super schön gewesen, wenn man diese Funktionalität ohne Assign und für komplexere Datentypen hätte.
Vielleicht ließt Emba das ja mit und stellt dich für diese Aufgabe [Ironie an]für Delphi 19.1[/Ironie aus] ein ;)

Leider unwahrscheinlich. Grade die Generics unterscheiden sich von den C++ Templates einfach viel zu sehr. Das wird man - selbst wenn man wollte - nicht aufrüsten können, ohne die Abwärtskompatibilität zu verlieren. Für komplexe Datentypen ist diese Funktionalität allerdings so oder so nicht verfügbar, da die Hardware dafür keine Unterstützung bereitstellt. In C++ ist es allerdings tatsächlich möglich auch komplexe Typen mit
Delphi-Quellcode:
std::atomic<T>
zu verwenden. In diesem Falle wird dann intern allerdings wieder auf Critical-Sections, Mutexe, etc. zurückgegriffen, aber dennoch manchmal eine schöne Abstraktion.

LTE5 31. Dez 2017 18:33

AW: AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
Zitat:

Das wird man - selbst wenn man wollte - nicht aufrüsten können, ohne die Abwärtskompatibilität zu verlieren
Ich denke das wäre verschmerzbar, wenn man dann dafür eine anständig funktionierende Funktionalität mit diesen Atomics hätte.
Deine ist auch gut keine Frage. Aber bei großen Projekten müsste man viel abändern.

himitsu 1. Jan 2018 15:50

AW: AtomicTypes - Atomare Boolean, Integer, Enum und Set Typen
 
Zitat:

// DON'T DO THIS! Not atomic!
I := J;
Seit gefühlt fast 12 Jahren (irgendwann nachdem Turbo Delphi erschien) gibt es im QC einen Eintrag/Wunsch, samt Lösungsvorschlag von mir, aber auf mich hört ja keiner.

Ich hatte mir gewünscht, dass es auch Operatoren für Initialize, Copy und Finalize gibt.
Es gibt bereits Funktionen in der System.pas dafür (Kopieren von Records/Arrays/Strings/Variants/Interfaces) und man müsste da nur noch den Aufruf dieser Operatoren dort einfügen. :cry:


Alle Zeitangaben in WEZ +2. Es ist jetzt 03:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf