Scala

Fragen zu allen anderen Programmiersprachen.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Scala

Beitrag von ts-soft »

Das Thema heißt Thread!
Die Verteilung von der Threads auf verschiedene Cores erledigt das OS automatisch,
so das man sich darum nicht scheren braucht und auch nicht sollte. Das nutzen von
Threads ermöglicht dem OS diese Optimierung.

Wobei die Anwendung auch nur bei speziellen Anwendungen sinnvoll ist, da z.B.
normale GUI Anwendungen 98% der Zeit nur im Eventloop auf den Menschen
warten :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: Scala

Beitrag von PMV »

edel hat geschrieben:Aber du wirst keinen Unterschied zur Laufzeit bemerken.
Also wenn ich ein Programm schreibe, das ...
... ganz oder zum teil interpretiert wird,
... zur Laufzeit sämtliche Variablen überwacht
... keine direkte Speichermanipulation erlaubt

Wie soll das genau so schneller sein wie ein Programm, das ...
... in Maschinensprache des Prozessors vor liegt
... keine Überwachung voraussetzt
... direkt effizient Speicher bearbeitet

Bitte erklär mir das. Eine Aussage ala "das geht" ist genau so hilfreich wie,
"das geht nicht".


@Skiller
Wie ts-soft schon sagte, heißt die Bibliothek von PureBasic "Thread",
das Thema dagegen würd ich eher als "Multithreading" betiteln.


@NicTheQuick
"Conditions" kann man sich selber Programmieren, wenn man es nötig hat.
Aber so weit ich das verstanden hab, kann man die direkt mit Mutex oder
eher Semaphore austauschen. Das Beispiel zumindest dort würde ich mit einer
Semaphore genau so lösen. :wink: Was die Fehlerbehandlung angeht, da
kann man sich tatsächlich streiten. Exceptions kann ich mir aber nicht vor-
stellen, dass so was überhaupt in Sprachen wie C++ oder PureBasic im
selben Maße machbar ist, wie in Java, wo alles so wie so überwacht wird.

Zur Laufzeit will ich keine solche Überwachung haben. Ich nutze PB gerade
weil ich schnellen und effizienten Code produzieren möchte. Fehler die auf-
tauchen können werden mit If-Blöcken an entsprechender Stelle behandelt
und bei Threads entsehen zwar komplexere Zusammenhänge, aber Sachen
wie Deadlocks sollten beim Debuggen aufgespürt werden, nicht wenn das
Programm fertig ausgeliefert wurde.

Was bietet denn C/C++ zur besseren Fehlerbehandlung zur Laufzeit bei
Threads? Das wäre mal interessant. :)

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Scala

Beitrag von NicTheQuick »

PMV hat geschrieben:Was bietet denn C/C++ zur besseren Fehlerbehandlung zur Laufzeit bei
Threads? Das wäre mal interessant. :)
Das funktioniert unter C++ genau so einfach wie unter Java. Ich bin jetzt allerdings etwas faul dir ein funktionierendes Beispiel zu basteln. ;)
Es gibt try-catch-Blöcke, man kann mit 'throw' Exceptions werfen, und man kann sie durch die Aufrufhierarchie einer Funktion weiter reichen. Und das passiert immer nur für den aktuellen Thread, was ja Sinn macht.

Für PB wäre es meiner Meinung nach wünschenswert, wenn man die 'OnError'-Sachen auch pro Thread bestimmen kann. Dazu läuft ja momentan auch noch ein anderer Thread irgendwo.

Und wegen den Conditions. Ich habe schon versucht das ganze nach zu bauen. Es ist aber nicht möglich, da es keine Notify-Funktionalität gibt. Conditions sind ja im Grunde eine ganz einfache Sache. Zwei Threads sind die selbe Condition bekannt. Einfachstes Beispiel: Thread 1 'push't etwas auf einen Stack und Thread 2 'pop't es wieder runter. Wenn der Stack leer ist, gibt es nichts zu 'pop'en, also führt Thread 2 dann 'Condition.wait()' aus. An dieser Stelle weiß der Scheduler des Betriebssystem, dass er Thread jetzt erst mal ignorieren darf, weil er sowieso nichts tun kann. Hat Thread 1 allerdings wieder etwas auf den Stack ge'push't, führt er direkt danach auch 'Condition.notify()' aus. Sobald das Lock für den Stack, das gerade von Thread 1 gehalten wurde, dann noch entsperrt wird, springt Thread 2 automatisch aus dem 'Condition.wait()' heraus und kann weiter machen. Ah, und das wichtigste hab ich vergessen. Da eine Condition immer an ein Lock gebunden ist, kann man 'Condition.wait()' auch nur sinnvoll nutzen, wenn der entsprechende Thread (im Beispiel Thread 2) das Lock auch genommen hat. Sobald der Thread dann aber wartet, entsperrt er das Lock um darauf zu warten ge'notify't zu werden. Nur so können andere Threads ihm auch ein 'Condition.notify()' senden, nämlich indem sie selbst das Lock halten.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: Scala

Beitrag von PMV »

Wartet die Ausführung in Condition.wait() so lange, bis Condition.notify()
aufgerufen wird, oder wird die Funktion so oder so verlassen, lediglich die
CPU wird geschont ähnlich wie bei einem PB-Aufruf von "Delay(x)"?

Stimmt ja, Try-Catch gibs auch für C++. :oops: Jaja, das kommt davon
wenn man sich immer nur Bruchhaft damit auseinander setzt und am Ende
alles vergisst. :roll: Also die OnErrorLib muss tatsächlich noch so angepasst
werden, dass es für jeden Thread extra läuft, das fehlt tatsächlich.
Und mir fällt grad noch ein, dass ja garkeine Möglichkeit mehr gibt, die
Programmausführung wieder auf zu nehmen nach dem Abfangen eines Fehlers.
Naja gut, das hat aber nun auch weniger mit Threads zu tun, fehlt aber dann
doch. Wenn diese zwei Punkte (wieder) existieren, kann ich von meiner Seite
aus zumindest hier nichts mehr beanstanden. :) Mit richtigen Try-Catch-Blöcken
und Exceptions werfen wird das ganze natürlich noch sauberer und übersichtlich.

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Re: Scala

Beitrag von edel »

@PMV

In beiden Sprachen, Java und .NET, kommt ein JIT-Kompiler zum Einsatz. Es wird also
der Bytecode nach Maschinensprache uebersetzt. Ausserdem gibt es weitere Optimierung,
damit der Code schneller laeuft.
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Re: Scala

Beitrag von remi_meier »

PMV hat geschrieben:
edel hat geschrieben:Aber du wirst keinen Unterschied zur Laufzeit bemerken.
Also wenn ich ein Programm schreibe, das ...
... ganz oder zum teil interpretiert wird,
... zur Laufzeit sämtliche Variablen überwacht
... keine direkte Speichermanipulation erlaubt

Wie soll das genau so schneller sein wie ein Programm, das ...
... in Maschinensprache des Prozessors vor liegt
... keine Überwachung voraussetzt
... direkt effizient Speicher bearbeitet

Bitte erklär mir das. Eine Aussage ala "das geht" ist genau so hilfreich wie,
"das geht nicht".
Da müssen wir doch erst einmal dazu sagen, dass PB kaum den Code
optimiert. Wirklich. Die "grossen" Compiler anderer Sprachen haben da
weit aufwändigere und effektivere Optimierungen parat.
Deshalb möchte ich deine Frage mal inklusive der Vorstellung erklären, PB
würde guten Code generieren.

1. Die langsame Startzeit von Java und C# ist unnötig. Verwendet man eine
Kombination von Interpreter und JIT, kann man ohne Probleme _sofort_
per Interpreter starten und das Programm dann per JIT in einer ruhigen
Phase kompilieren. Aber klar, das verteilt diesen Overhead.

2. Der Teil der Laufzeit, in dem in deinem Programm "Variablen überwacht"
werden, ist gering. Der Rest kann so optimiert werden, dass das nicht
mehr nötig ist. Stell dir mal vor, du hast eine Funktion, welche ein Bild
verarbeitet und komprimiert. Wenn der Compiler weiss, dass sowieso nichts
dazwischen funken kann, wird er diese "Überwachung" einfach ausschalten
und diese Funktion wie ein effizienter C-Compiler optimieren. Das geht bei
den meisten rechenintensiven Funktionen, wenn sie richtig programmiert
sind.

3. Nun zur eigentlichen Erklärung, warum JIT+Interpreter schneller sein
kann als selbst gut optimierter Code:
Es gibt viele effektive Techniken zu "Runtime Optimizations" oder "JIT
Optimizations". Zum Einen erlauben es solche Optimierungen, direkt auf
den verwendeten Prozessor zu kompilieren (anstatt generisch für alle
Möglichen) und zum Anderen führen JIT-Compiler zur Laufzeit Statistiken
mit. Beispielsweise wie oft eine Funktion aufgerufen wird -> Kandidat zum
inlinen, wie oft dieser Speicherbereich genutzt wird -> schiebe ihn in den
CPU-Cache, wie das "Access-Pattern" im Speicher aussieht -> führe
verschiedene Speicherbereiche zusammen (besseres CPU-Caching), wie
oft wird das ELSE eines IFs ausgeführt -> helfe der CPU-Branch-Prediction
oder welche Funktionen dieser _dynamisch_ geladenen Bibliothek werden
immer wieder verwendet -> Inlining oder sonst die Code-Lokalität erhöhen.

Das sind nur einige der vielen Optimierungsmöglichkeiten, welche erst durch
Bytecode+Interpreter+JIT möglich werden.


greetz
Remi

tl;dr... was edel sagt, nur länger

Edit: http://www.javaperformancetuning.com/news/qotm042.shtml
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: Scala

Beitrag von PMV »

Schöne Ausführung remi, danke.

Aber jede zu überwachende Optimierung und Statistik benötigt wieder
CPU-Zyklen, die das ganze nicht nur später beschleunigen können,
sondern grundsätzlich ausbremsen. Wie soll das ganze Wissen den
überhaupt angesammelt werden, wenn dadurch nicht zusätzlich
CPU-Zeit verbraten wird? Ein Code kann nur bis zu einem gewissen
Punkt optimiert werden. Sagen wir, das ist Zustand A. Code, der
durch JIT + Interpreter bearbeitet wird, kann zwar den zu verwalten-
den Code auf den Zustand A bringen, doch insgesamt brauchen alle
Mechanismen zusammen so viel, das es bei Zustand B oder gar C
bleibt. Der Zustand A ist so garnicht erreichbar, dafür müsste sich
das ganze System selber abschalten, nachdem alles kompiliert wurde.
Und wenn dem so wäre, dann könnte man auch direkt das ganze ein mal
optimieren lassen und dann die Daten anbieten, so dass beim ersten
Ausführen sofort der beste Code produziert und das Programm ohne
Overhead perfekt läuft.

Und wenn Java (und .NET) dafür garantieren würden, dass der Zustand A
immer erreicht wird, dann frage ich mich, warum zeitintensive Dinge nicht
immer damit realisiert werden? Es wäre ja mit die beste Sprache dann
für so etwas. Sie analysiert zur Laufzeit die besten Optimierungen und
erstellt darauß den besten Maschinencode. Ich hab mich im Studium mit
Java auseinander setzten "dürfen", aber war nie davon überzeugt ... wenn
ich Wissenslücken hab, wäre ich euch sehr dankbar, wenn ihr diese stopft. :)
Das Java nicht super Langsam ist weis ich auch ... das liegt mit an den
Entwicklern, so wie es bei jeder Sprache der Fall ist ... aber Java hat von mir
bisher immer das Prädikat "langsam" erhalten. Egal was ich damit machen
wollt.

Ich weis, das PB keinen optimierten Code generiert, hier ist das
vergleichbar wohl mit Zustand D-H ... aber dafür gibs ja auch noch ASM,
oder eben andere Sprachen wie C/C++, die Kompiler bieten um das
optimalste Ergebnis zu erzielen.

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Scala

Beitrag von Nino »

remi_meier:
Sehr interessant, vielen Dank für die ausführlichen Erläuterungen!

Grüße, Nino
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: Scala

Beitrag von DarkDragon »

PMV hat geschrieben:Und wenn Java (und .NET) dafür garantieren würden, dass der Zustand A
immer erreicht wird, dann frage ich mich, warum zeitintensive Dinge nicht
immer damit realisiert werden? Es wäre ja mit die beste Sprache dann
für so etwas. Sie analysiert zur Laufzeit die besten Optimierungen und
erstellt darauß den besten Maschinencode. Ich hab mich im Studium mit
Java auseinander setzten "dürfen", aber war nie davon überzeugt ... wenn
ich Wissenslücken hab, wäre ich euch sehr dankbar, wenn ihr diese stopft. :)
Das Java nicht super Langsam ist weis ich auch ... das liegt mit an den
Entwicklern, so wie es bei jeder Sprache der Fall ist ... aber Java hat von mir
bisher immer das Prädikat "langsam" erhalten. Egal was ich damit machen
wollt.
1. Weil es die Sicherheit nicht zulässt dass so ein komplexes System dahintersteckt (Flugzeuge, Raketen, Schwarze Löcher etc.).
oder
2. Weil die Programme (zumindest bei .NET, bei Java gibts Jazelle) in erster Linie nur auf multithreaded Betriebssystemen laufen die gleich am Start schon 20 andere Programme parallel laufen lassen.

Doch die Industrie nutzt Java/.NET wo sie nur kann. Das bekommst du mit sobald du nichtmehr für Endkunden produzierst (Endkunden haben immer was zu meckern und wenn es nur wegen einem zusätzliches Runtime Paket ist).
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: Scala

Beitrag von PMV »

@nic

Code: Alles auswählen

; ----- Condition ----------------
Structure Condition
  mutex.i
  semaphore.i
EndStructure

Procedure.i CreateCondition(mutex.i)
  Protected *con.Condition = AllocateMemory(SizeOf(Condition))
  *con\mutex = mutex
  *con\semaphore = CreateSemaphore()
  ProcedureReturn *con
EndProcedure

Procedure WaitCondition(*condition.Condition)
  UnlockMutex(*condition\mutex)
  WaitSemaphore(*condition\semaphore)
  LockMutex(*condition\mutex)
EndProcedure

Procedure SignalCondition(*condition.Condition)
  SignalSemaphore(*condition\semaphore)
EndProcedure

Procedure FreeCondition(*condition.Condition)
  FreeMutex(*condition\mutex)
  FreeSemaphore(*condition\semaphore)
  FreeMemory(*condition)
EndProcedure
; ---------------------------------
; ---------------------------------

; Beispiel aus Java-Doc:
; http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html


Global lock = CreateMutex()
Global notFull = CreateCondition(lock)
Global notEmpty = CreateCondition(lock)
#MaxItems = 100
Global Dim items.s(#MaxItems - 1)
Global putptr, takeptr, count

Procedure put(x.s)
  LockMutex(lock)
  While count >= #MaxItems - 1
    WaitCondition(notFull)
  Wend
  items(putptr) = x
  putptr + 1
  If putptr = #MaxItems : putptr = 0 : EndIf
  count + 1
  SignalCondition(notEmpty)
  UnlockMutex(lock)
EndProcedure

Procedure.s take()
  Protected x.s
  LockMutex(lock)
  While count =< 0
    WaitCondition(notEmpty)
  Wend
  x = items(takeptr)
  takeptr + 1
  If takeptr = #MaxItems : takeptr = 0 : EndIf
  count - 1
  SignalCondition(notFull)
  UnlockMutex(lock)
  ProcedureReturn x
EndProcedure




; ---- Test ----
; Compileroption Threadsafe aktivieren!

Procedure ErstelleWerte(Count.i)
  Protected i.i, wait.i
  
  For i = 1 To Count
    wait = Random(1000)
    Delay(wait)
    put(Str(i) + ". test")
    Debug Str(i) + ". Wert erstellt (" + Str(wait) + " ms)"
  Next
EndProcedure  

CreateThread(@ErstelleWerte(), 100)
  
Define i.i, wait.i
For i = 1 To 100
  wait = Random(1000)
  Delay(wait)
  Debug "Wert " + Chr(34) + take() + Chr(34) + " genommen (" + Str(wait) + " ms)"
Next
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Antworten