Laden...

Gleitkommaoperationen, was nutzt ihr als Beschleuniger?

Erstellt von Siassei vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.582 Views
S
Siassei Themenstarter:in
401 Beiträge seit 2008
vor 13 Jahren
Gleitkommaoperationen, was nutzt ihr als Beschleuniger?

Servus,

Beschleunigungsmöglichkeiten für Gleitkomazahlen gibt es mittlerweile wie Sand am Meer. Als Hobbyprogrammierer hätte ich da ein paar Fragen.

1.) Nutzt .NET, Mono oder Java bereits einige Befehle von SSE?
2.) Lassen sich Optimierungen über den Compiler durchführen?

3.) Für die CPU und GPU gibt es bereits CUDA, ATI Stream und OpenCL. Was nutzt hier bereits? Falls ja, was würdest du benutzen wenn du die Wahl hättest?

4.) Wie sieht es mit dem Umgang mit Integer's aus? Gibt es hier überhaupt eine gute Wahl, ala SSE, CPU + GPU, .... ?
z.B. für eine BigInteger oder Rational-Klasse, die häufig Operationen (+, -, *) ausführt. (sehr große Zahlen)
5.) Gibt es für Fortran überhaupt noch gute Compiler, die man als Student oder OpenSource-Vereinigung nutzen kann?

Gruß,
Thomas

458 Beiträge seit 2007
vor 13 Jahren

Als Gleitkomaoperationsbeschleuniger benutze ich meistens Jack Daniels... SCNR

be the hammer, not the nail!

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

ad 1) .net nicht dass ich wüsste, zu Mono und Java kann ich nichts sagen

ad 2) der Compiler in .net (C# und JITer) optimieren fast nichts - die sind dumm 😉

ad 3) hab mal mit Accelerator von Microsoft Research rumgespielt

ad 5) FTN-Compiler gibt es genügend, die von den großen Hestellern sind alle gut. Für Studenten gibts meist Academic Versions, für OpenSource-Nutzung gibts meist keine speziellen Lizenzen.

Für numerische Berechnungen verwende ich nach wie vor FTN und kompiliere dort eine C-Style-DLL welche in C# mit P/Invoke verwendet wird.

@aequitas: 😄

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

5.658 Beiträge seit 2006
vor 13 Jahren

1.) Nutzt .NET, Mono oder Java bereits einige Befehle von SSE?

Ich gehe davon aus, daß der JITer CPU-spezifische Befehler verwendet. In .NET bzw. CLR gibt es meines Wissens dafür keinen eigenen Befehlssatz.

2.) Lassen sich Optimierungen über den Compiler durchführen?

Siehe 1.

3.) Für die CPU und GPU gibt es bereits CUDA, ATI Stream und OpenCL. Was nutzt hier bereits? Falls ja, was würdest du benutzen wenn du die Wahl hättest?

Genutzt hab ich sowas noch nicht, weil das nur für bestimmte Aufgabengebiete sinnvoll ist.

4.) Wie sieht es mit dem Umgang mit Integer's aus? Gibt es hier überhaupt eine gute Wahl, ala SSE, CPU + GPU, .... ? z.B. für eine BigInteger oder Rational-Klasse, die häufig Operationen (+, -, *) ausführt. (sehr große Zahlen)

Die CPU ist dafür gemacht mit 32 Bit bzw. 64Bit-Integers umzugehen. Für alle anderen (größere) Zahlen gibt es keine eigenen Befehle.

Was genau hast du vor, evtl. wäre es einfacher eine konkrete Frage zu stellen?

Weeks of programming can save you hours of planning

S
Siassei Themenstarter:in
401 Beiträge seit 2008
vor 13 Jahren

@gfoidl
Der Fortran-Compiler von GCC ist ja nicht gerade berauschend. Erzeugt der Intel-Fortran-Compiler guten Code?
Intel bietet zur Zeit für Linux oder non-commercial vieles kostenlos an.
Non-Commercial Software Development

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo,

Der Fortran-Compiler von GCC ist ja nicht gerade berauschend.

AFAIK wandelt der GCC den FTN-Code nach C-Code und kompiliert diesen. Das ist Murcks, da hast du recht.

Erzeugt der Intel-Fortran-Compiler guten Code?

Ist mMn zusammen mit dem Lahey Fujitsu Compiler einer der besten.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

S
Siassei Themenstarter:in
401 Beiträge seit 2008
vor 13 Jahren

3.) Für die CPU und GPU gibt es bereits CUDA, ATI Stream und OpenCL. Was nutzt hier bereits? Falls ja, was würdest du benutzen wenn du die Wahl hättest?

Genutzt hab ich sowas noch nicht, weil das nur für bestimmte Aufgabengebiete sinnvoll ist.

Ja, genau. Vieles, sehr vieles fehlt hier.
Im Allgemeinen ist der optimale Ablauf: Eingabe -> einfache math. Berechnungen -> Ausgabe
und genau hier liegt das Problem. Wann hat man das? 😦

Da die Frage bereits gefallen ist.
Ich schreibe gerade an einem kleinen, eigenen RayTracer in Scala (JVM). Dieser soll ein Voxelmodell (erstes Modell 3D Fraktal) visualisieren. Zur Zeit berechne ich nur das direkte Licht. Die Berechnung eines Bildes dauert etwas 20 min. Ich möchte dies nun auf 200 ms senken 😃

Der Profiler hat gezeigt, dass die Zeit beim erstellen der Klassen Vektor, Intersection, Point, ... und double-Operationen (alleine ~80% der Zeit) verloren geht.

Bei CUDA, ATI Stream und OpenCL muss man die Algorithmen extrem verändern/anpassen. Dies führt zu einer Erhöhung der benötigten Ray's pro Pixel --> Aufwand (Berechnungen, Schnittpunkttest) steigen extrem an

Ich möchte daher bei Scala bleiben und später auch eine Mono-Lösung erstellen.

6.911 Beiträge seit 2009
vor 13 Jahren

Hallo Thomas,

Die Berechnung eines Bildes dauert etwas 20 min. Ich möchte dies nun auf 200 ms senken

Es fällt mir schwer zu glauben dass das auch mit GPU so einfach ist. Auch dort müsstes du eine Cluster haben - denn Raytracing lässt sich afaik ja gut parallelsieren und dieses ist nicht nur auf lokale Prozessor-/GPU-kerne beschränkt.
In .net verteile ich die Aufgaben einfach per WCF auf dem Cluster. Ist nichts besonderes: ein Rechner verwaltet die Operationen und alle anderen rechnen 😉

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Siassei,

die Optimierungen unterschiedlicher Compiler werden nicht so unterschiedlich sein, dass du damit einen Faktor von 6000 überbrücken kannst. Selbst mit eine händische Optimierung des Codes mittels SSE-Befehlen wird man diesen Faktor wohl nicht erreichen. Daher sehe ich als einzige Chance die Grafikkarte per CUDA bzw. ATI Stream zu nutzen. Da sich Raytracing hervorragend für Parallelisierung eignet, sehe ich hier echte Chancen, vorausgesetzt, die Karte hat genügend Rechenwerke und ist auch sonst leistungsfähig genug. Zwischen einem unoptimierten C#/Java-Programm und einer CUDA/ATI Stream-Version kann bei Raytracing wohl durchaus ein vierstelliger Faktor liegen.

herbivore

S
8.746 Beiträge seit 2005
vor 13 Jahren
5.658 Beiträge seit 2006
vor 13 Jahren

3.) Für die CPU und GPU gibt es bereits CUDA, ATI Stream und OpenCL. Was nutzt hier bereits? Falls ja, was würdest du benutzen wenn du die Wahl hättest?

Genutzt hab ich sowas noch nicht, weil das nur für bestimmte Aufgabengebiete sinnvoll ist.
Ja, genau. Vieles, sehr vieles fehlt hier.
Im Allgemeinen ist der optimale Ablauf: Eingabe -> einfache math. Berechnungen -> Ausgabe
und genau hier liegt das Problem. Wann hat man das? 😦

Wenn du das auf die GPU-basierenden Verfahren beziehst, dann ist das nicht ganz richtig. Viel wichtiger ist, daß du viele gleichzeitige Eingabedaten hast, die alle unabhängig voneinander berechnet werden können. Nur dann lohnt es sich, die Daten in den Videospeicher zu kopieren, dort verarbeiten zu lassen und die Daten wieder zurück in den RAM zu kopieren, um damit weiterzuarbeiten.

Was ich sagen will: Der Algorithmus wird nicht automatisch schneller, nur weil du ihn von der GPU berechnen läßt.

Ich schreibe gerade an einem kleinen, eigenen RayTracer in Scala (JVM). Dieser soll ein Voxelmodell (erstes Modell 3D Fraktal) visualisieren.

Grafikkarten sind nicht dafür entwickelt worden, Raytracing zu berechnen, deshalb brauchst du entsprechende Datenstrukturen, die sich auf die Funktionsweise der GPU abbilden lassen. Keine Ahnung was Scala (JVM) ist, aber es wird schon in die Richtung gehen. Die Entwicklung wird aber seit mehreren Jahren von den Herstellern (ATI, NVidia) und im akademischen Bereich vorangetrieben. In beiden Bereichen wird darüber veröffentlicht, hast du dich zu den verscheidenen Verfahren mal belesen?

Zur Zeit berechne ich nur das direkte Licht. Die Berechnung eines Bildes dauert etwas 20 min. Ich möchte dies nun auf 200 ms senken 😃

Wie kommst du denn auf den Wert? Und für welche Objekte bzw. Szene soll der Wert gelten? Eine einfache Kugel kannst du sicher noch wesentlich schneller raytracen, selbst auf der CPU, und selbst mit naiven Algorithmen.
Aber einen Algorithmus von 20 min auf 200 ms zu beschleunigen, da reicht es nicht, einfach die GPU statt die CPU zu beschäftigen. Da mußt du grundlegende Änderungen an deinem Algorithmus vornehmen!

Der Profiler hat gezeigt, dass die Zeit beim erstellen der Klassen Vektor, Intersection, Point, ... und double-Operationen (alleine ~80% der Zeit) verloren geht.

Das ist schonmal ein gutes Zeichen, denn genau das würde man ja von so einem Algorithmus erwarten. Statt aber nach einer komplett neuen Lösung zu suchen, kannst du den vorhandenen Algorithmus z.B. auch erst einmal optimieren, also:

  • überflüssige Berechnungen eliminieren
  • komplexe Berechnungen vereinfachen (evtl. auch nur Näherungswerte berechnen, wenn sie visuell nicht erkennbar sind)

Also zusammenfassend:

  • Prozessorspezifische Gleitkommaoperationen werden automatisch vom JIT-Compiler ausgegeben, du hast keinen Einfluß darauf.
  • Den wahrscheinlich größten Performancegewinn hat man durch einen optimalen Algorithmus
  • Durch Parallelisierung kannst du alle CPU-Kerne ausnutzen
  • Wenn der Algorithmus zumindest zum Teil auch auf der GPU lauffähig ist, kann man die Ausführungszeit (evtl.) weiter verringern.

Halt uns mal auf dem Laufenden, klingt nach einem interessanten Projekt!

Schöne Grüße
Christian

Weeks of programming can save you hours of planning

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo MrSparkle,

Viel wichtiger ist, daß du viele gleichzeitige Eingabedaten hast, die alle unabhängig voneinander berechnet werden können.

genau das ist doch beim Raytracing der Fall.

Grafikkarten sind nicht dafür entwickelt worden, Raytracing zu berechnen

Das stimmt zwar, aber wir reden hier auch nicht darüber, die Grafikkarte als Grafikkarte zu verwenden, sondern per CUDA/ATI Stream, also für General Purpose Berechnungen. Da sich nun Raytracing sehr gut parallelisieren lässt und eine Grafikkarte viele schnelle parallele Recheneinheiten hat und die Bedingung aus dem ersten Zitat auch erfüllt ist, lässt sich durch die Nutzung einer Grafikkarte selbst dann eine erhebliche Beschleunigung erwarten, der Algorithmus im Grunde unverändert bleibt.

Wenn es im Algorithmus selbst noch Optimierungspotenzial gibt, um so besser.

Wie kommst du denn auf den Wert?

Das eine ist die gemessene IST-Zeit und das andere die gewünschte SOLL-Zeit. Ob sie sich erreichen lässt, steht auf einem anderen Blatt, aber ich halte das durchaus im Bereich des machbaren.

herbivore

5.658 Beiträge seit 2006
vor 13 Jahren

Hi herbivore,

Viel wichtiger ist, daß du viele gleichzeitige Eingabedaten hast, die alle unabhängig voneinander berechnet werden können.
genau das ist doch beim Raytracing der Fall.

Nicht ganz, das trifft zwar für die Pixel zu, die berechnet werden sollen, aber die Verwaltung der Geometrie oder gar der Szene geht nur auf Umwegen, z.B. über Voxel o.ä. Die Berechnung, ob ein Strahl ein Objekt trifft bzw. welche Objekte von einem Strahl getroffen werden, ist daher nicht ganz trivial.

Grafikkarten sind nicht dafür entwickelt worden, Raytracing zu berechnen
Das stimmt zwar, aber wir reden hier auch nicht darüber, die Grafikkarte als Grafikkarte zu verwenden, sondern per CUDA/ATI Stream, also für General Purpose Berechnungen. Da sich nun Raytracing sehr gut parallelisieren lässt und eine Grafikkarte viele schnelle parallele Recheneinheiten hat und die Bedingung aus dem ersten Zitat auch erfüllt ist, lässt sich durch die Nutzung einer Grafikkarte selbst dann eine erhebliche Beschleunigung erwarten, der Algorithmus im Grunde unverändert bleibt.

Im Prinzip wird für solche Anwendungen auch die ganz normale Grafik-Pipeline verwendet. Die Eingangsdaten werden als "Textur" an die GPU übermittelt, und die eigentlich Berechnung wird in Form von Vertex- oder PixelShadern durchgeführt. Wie die API das dann nach außen darstellt, ist etwas völlig anderes.
Und Raytracing läßt sich zwar relativ einfach parallelisieren, aber die Frage ist trotzdem, wie man die zu berechnenden 3D-Modelle in einem solchen Datenformat überhaupt darstellen kann, daß die eigentliche Berechnung dann immer noch schneller ist, als auf der CPU.

Christian

Weeks of programming can save you hours of planning