PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Gleitkomma-Performance auf Intel und PowerCPU


pajofego
2008-02-06, 19:42:12
Hallo zusammen,

folgende Frage zu meiner Untersuchung:

Ich habe Ubuntu auf der Xbox360 laufen. Dort werkelt eine 3-core PowerPC, mit 3.2 GHz. Mich hat einmal die Gleitkomma Performance interessiert. Dabei habe ich ausgehend von folgendem Code:


do
{
d = (double)i * d / (d + 2.0);
} while (--i);


immer eine weitere Funktion drangehängt. Siehe beigelegte Datei. Es wurde stets mit der Optimierungsoption -O3 kompiliert.

Vergleichs-Intelsystem ist ein T5600 1.83 GHz.

Ich bin ein bischen darüber verwundert, dass die PowerCPU fast immer deutlich hinter dem Intel fällt. Ausreißer hier, bei Verwendung von exp(x). Ich ging eigentlich davon aus, dass die PowerCPU schneller wäre als der Intel. Kann es am gcc liegen, dass da nicht ausreichen performanter Code für die PowerCPU generiert wird? Oder sind es doch eher hardwareseitige Beschränkungen? Gibt's performancesteigende Möglichkeiten, die ich ausprobieren kann? Tipps wären super.

Ich hatte heute die Möglichkeit einige Beispiele an einem Opteron Server durchzuführen. Der war um einige Längen schneller als der Intel und deklassiert die PowerCPU deutlich...!

Danke und viele Grüße

pajofego

Neomi
2008-02-06, 20:21:55
Der Xenon ist deutlich abgespreckt in manchen Bereichen, daher nicht mit einem regulären PowerPC zu vergleichen.

Es gibt einige Penalties, die bei dieser CPU zuschlagen können, bei dieser Schleife wird aber höchstwahrscheinlich alleine in Registern gearbeitet und die meisten kommen nicht zum Tragen. Eine Division ist allerdings dabei, und die ist wenn ich mich jetzt nicht sehr irre nicht gepipelined. Und da die Pipeline mit knapp über 40 Stufen nicht gerade kurz ist, wird die weitere Abarbeitung extrem verzögert.

Kannst du mal das Disassembly von der Schleife posten?

Edit: das Casting von int zu double habe ich gerade erst bemerkt, das ist bei dieser CPU auch sehr böse. Wenn du einen weiteren double mitführst und in jedem Durchlauf 1.0 davon abziehst, dann sollte das die Schleife schonmal ein gutes Stück beschleunigen.

MikeB
2008-02-06, 21:19:52
Ich schliesse mich da meinem Kollegen Neomi voll und ganz an (ausser dass xenon eigentlich für die gpu steht?). Die Umwandlung von Integer nach Double ist für den PPC absolut tödlich. (ohne sse für den Intel auch)
Zusätzlich ist diese Art Arithmetik für eine in-order CPU mit langen Pipelines unverträglich.
Dazu kommt noch, dass sin() und pow() Compiler-Intrinsics sind und nicht nativ von der FPU bearbeitet werden.

Ich weiss leider nicht wie weit ich da an NDAs von Microsoft gebunden bin um bei LHS-penalties zu helfen.
Die Ergebnisse von der X360 lassen sich nicht auf die normalen PPCs wie g4/5 übertragen.

Michael

Neomi
2008-02-06, 21:46:12
(ausser dass xenon eigentlich für die gpu steht?)

Die GPU wäre dann Xenos. Bei den beiden Namen muß ich allerdings auch erst vorher googlen, ansonsten würde ich dank 50:50-Chance mit 98% Wahrscheinlichkeit den falschen nennen. :D

pajofego
2008-02-06, 22:19:31
Also ich hoffe ich habe den kompletten interessierenden Teil kopiert:

doubleTest:
mtctr 3
stwu 1,-32(1)
lis 0,0x4330
lis 9,.LC4@ha
lis 11,.LC6@ha
lfs 9,.LC4@l(9)
lis 9,.LC2@ha
lfs 10,.LC6@l(11)
lfd 11,.LC2@l(9)
lis 9,.LC1@ha
lfs 0,.LC1@l(9)
stw 3,28(1)
stw 0,24(1)
nop
nop
lfd 13,24(1)
fsub 12,13,0
.p2align 4,,15
.L30:
fmul 0,11,12
fadd 13,11,9
fsub 12,12,10
fdiv 11,0,13
bdnz .L30
fctiwz 0,11
stfd 0,16(1)
nop
nop
lha 3,22(1)
addi 1,1,32
blr
.size doubleTest,.-doubleTest
.section .rodata.cst4
.align 2
.LC11:
.long 1501560832
.align 2
.LC13:
.long 1501560836
.section ".text"
.align 2
.p2align 4,,15
.globl scaleControl
.type scaleControl, @function

Basis Code für das obere Asssembly der Schleife habe ich nach euren Tipps wie folgt geändert:


short doubleTest(unsigned long i)
{
double d = 0.0;
double d_i = (double)i;
do
{
d = d_i * d / (d + 2.0);
d_i -= 1.0;
} while (--i);

return (short)d;
}


Die Steigerung der Performance für:


d = d_i * d / (d + 2.0) + (exp(d_i) + 1e-9);


von 26 sec auf 24 runtergegangen. Also eher marginal.

Gruß
pajofego

MikeB
2008-02-06, 22:27:08
Naja, dann ist es wohl der fdiv der hier komplett limitiert...

Dem gcc kann man hier echt keinen Vorwurf machen...

pajofego
2008-02-06, 22:47:16
Vielleicht war's jetzt von meiner Seite alles ein bischen ungeordnet:

Nachdem ich die Umwandlung von int nach double geändert haben wurde die Schleife mit folgendem Code:


d = d_i * d / (d + 2.0);


unter 1 sec. ausgeführt. Vorher 4 sec. Also das war schon eine deutliche Verbesserung.

Lediglich sobald ich dem oberen Code die Addition einer exp(d_i) einfüge, fällt die Performance dramatisch. Wieso bringt exp() die CPU so zum Stocken?

MikeB
2008-02-06, 22:53:45
Die exp() ist wohl auch eine Funktion, also nicht von der FPU unterstützt. Es sind dann eine gigantische Menge an Additionen und Multiplikationen nötig um exp() zu berechnen.

pajofego
2008-02-06, 23:08:12
Also ist der Funktionsumfang der FPU bei der Xbox 360 wohl ordentlich gekürzt worden. Ansonsten kann mir den erheblichen Leistungseinbruch bei der Verwendung von trigo, sqrt, pow, und ähnlichen Funktionen nicht erklären. Stinknormale addition, subtraktion, multiplikation und division werden wohl normal "schnell" ausgeführt. Ich werde weitere Untersuchungen machen wo weitere Leistungslecks gegenüber normal ausgestatter CPUs liegen. Falls ihr weiter Infos habt, nur her damit.

Danke,
Gruß
pajofego

ethrandil
2008-02-07, 00:39:45
Ich verstehe grade nicht ganz genau was du höden möchtest. Möchtest du konkrete Hiwneise, wie du diese Schleifen beschleunigen kannst? Oder nur allgemein Hinweise über Performanceprobleme der genannten CPUs? Oder nur einen wenig aussagenden Benchmarkwert für FP-Performance?

mfg
- eth

pajofego
2008-02-07, 07:57:48
Hi, die Schleife diente nur zu Testzwecken um zu schauen was die cpu der xbox kann. Eine art synthetischer Testfall. Mich interessieren eher Tipps, welche Probleme hinsichtlich Performance bei Codeportierung von i386 auf ppc zu erwarten. Wie oben gesehen sind Typumwandlung wie ein abgespeckter Funktionsumfang in der FPU schon mal ein paar ordentliche Bremsen. Um deine Frage direkt zu beantworten, suche ich Guidelines für effektiven Code auf der PowerCPU der Xbox360, sofern es welche gibt.

Gruß
pajofego

Ganon
2008-02-07, 09:26:20
Aber dabei bedenken das die CPU der XBOX360 nicht für PowerPC-CPUs allgemein gilt.

Und falls du direkt für die XBOX360 CPU etwas machen willst, will ich noch mal an die recht große VMX128-Einheit(en) (ähnlich wie Altivec der G4s) erinnern, falls der Code SIMD fähig ist.

MikeB
2008-02-07, 10:17:25
Hi, die Schleife diente nur zu Testzwecken um zu schauen was die cpu der xbox kann. Eine art synthetischer Testfall. Mich interessieren eher Tipps, welche Probleme hinsichtlich Performance bei Codeportierung von i386 auf ppc zu erwarten. Wie oben gesehen sind Typumwandlung wie ein abgespeckter Funktionsumfang in der FPU schon mal ein paar ordentliche Bremsen. Um deine Frage direkt zu beantworten, suche ich Guidelines für effektiven Code auf der PowerCPU der Xbox360, sofern es welche gibt.

Gruß
pajofego

Solche guidelines gibt es schon, sind aber nur xbox-Entwicklern zugängig, also nicht öffentlich.
Deine Testschleife ist nicht sehr representativ, sin() und pow() braucht man in der Praxis nicht in dieser Menge.
Versuch mal lieber solche Sachen wie Matrizenmultiplikation und ähnliches.
Umwandlungen zwischen integer und float versucht man auch auf dem PC so gut wie möglich zu vermeiden.

Michael

Gast
2008-02-07, 12:20:47
ich denke die double rechnerei ist suboptimal. kleine enge schleifen bei einer langen in-order-pipeline sind auch "Arsch".
Du brauchst eine lange Funktion die nur rechnet und keine Sprünge hat.
Intel CPUs sind nunmal dafür angepasst worden um den 08/15 code schnell abzuarbeiten. und da die meisten wirklich so einen schlechten Code schreiben wie du da in deinen Tests (ja ich verstehe dass das nur Tests waren und sonst niemand sowas in richtigen Applikationen machen würde;) ), laufen solche Dinge auf Intel nunmal sehr gut.
Ein wirklich gut geschriebener Code sollte auf der Xbox schneller sein. Du hast also an sich eigentlich nur einen Benchmark gemacht wie gut du schnellen Code schreiben kannst.

Gastomio
2008-02-07, 13:27:14
Frage:
Wieviele logische Prozessoren zeigt bei dir Ubuntu an?

Zum Rest:
Ohne Altivec ist die Messung für die Tonne.

MikeB
2008-02-07, 13:47:52
Ohne Altivec ist die Messung für die Tonne.

Dieses Statement auch...

Gast
2008-02-07, 16:29:26
Dieses Statement auch...

Und dieses ebenfalls... xD

Mit welchem Kernel läuft Ubuntu bei pajofego denn? Sicher, dass die Bearbeitung von zwei Threads pro Kern bei ihm überhaupt unterstützt werden?

pajofego
2008-02-07, 19:25:58
Hi zusammen,

ich denke folgender Link beantwortet die meisten hier gestellten Fragen: http://www.free60.org/wiki/CPU

Vor allem folgender Absatz:

* We have full SMP support, so we can use all three cores.
* However, we currently need to disable the secondary threads because of a yet-to-be analyzed stability issue.
* The CPU is quite slow on general purpose code. Due to the non out-of-order execution core, it heavily relies on the compiler to do proper optimizations. GCC currently doesn't know how to do this, resulting in running but very inefficient code.
* The Cell people are working on ppu-gcc, from which the Xenon will benefit as well, as the PPC cores is quite similiar to the Cell's PPU.


Wenn ich alles richtig verstehe, dann ist compilerseitig demnächst mit einer Verbesserung zu rechnen.

Gruß
pajofego

Gast
2008-02-07, 20:11:26
Will ja nix sagen, aber ich hatte es geahnt. ;)

Gast
2008-02-08, 01:37:47
naja, man sollte nicht auf wunder hoffen.

pajofego
2008-02-08, 19:13:08
naja, man sollte nicht auf wunder hoffen.

Ist dein Kommentar auf die Arbeit an ein ppc-gcc gerichtet?

beos
2008-02-09, 05:34:30
Hi zusammen,

ich denke folgender Link beantwortet die meisten hier gestellten Fragen: http://www.free60.org/wiki/CPU

Vor allem folgender Absatz:

* We have full SMP support, so we can use all three cores.
* However, we currently need to disable the secondary threads because of a yet-to-be analyzed stability issue.
* The CPU is quite slow on general purpose code. Due to the non out-of-order execution core, it heavily relies on the compiler to do proper optimizations. GCC currently doesn't know how to do this, resulting in running but very inefficient code.
* The Cell people are working on ppu-gcc, from which the Xenon will benefit as well, as the PPC cores is quite similiar to the Cell's PPU.


Wenn ich alles richtig verstehe, dann ist compilerseitig demnächst mit einer Verbesserung zu rechnen.

Gruß
pajofego

Gibt denn einen guten Artikel zu den PPC's der Box ... und in wie fern die angespeckt wurden ?

Gast
2008-02-10, 13:22:31
Kann jemand (CPU unabhängig) erklären warum ein cast von int to float so lange dauert?

Neomi
2008-02-10, 13:56:36
Kann jemand (CPU unabhängig) erklären warum ein cast von int to float so lange dauert?

Nein, denn das ist abhängig von der CPU und läßt sich generell auch als schnelle Operation implementieren.

Trap
2008-02-10, 14:00:33
Es ist durchaus möglich CPUs zu bauen bei denen der cast schnell ist.

Man baut sie nur nicht, weil es sich nicht lohnt. Der Aufwand dafür ist hoch und der Nutzen sehr gering. Der Aufwand ist hoch weil die Repräsentation von int und float sich unterscheidet und die Einheiten dafür in der CPU getrennt sind, der Nutzen gering weil in performancekritischem Code die Wandlung fast immer vermieden werden kann.

Gast
2008-02-10, 20:52:48
Ok, danke :)

Coda
2008-02-11, 00:13:29
Es ist durchaus möglich CPUs zu bauen bei denen der cast schnell ist.

Man baut sie nur nicht, weil es sich nicht lohnt. Der Aufwand dafür ist hoch und der Nutzen sehr gering. Der Aufwand ist hoch weil die Repräsentation von int und float sich unterscheidet und die Einheiten dafür in der CPU getrennt sind, der Nutzen gering weil in performancekritischem Code die Wandlung fast immer vermieden werden kann.
Der Cast von Int->Float ist auf x86 doch schnell (FILD). Was langsam ist ist Float->Int und zwar, weil die FPU auf Round-To-Nearest steht und man deshalb erst auf Truncate umschalten muss und wieder zurück, weil der C-Standard das so erfordert. Ansonsten wäre es nämlich auch schnell (FIST - was ein schöner Opcode-Name).

pajofego
2008-02-12, 00:27:40
Und falls du direkt für die XBOX360 CPU etwas machen willst, will ich noch mal an die recht große VMX128-Einheit(en) (ähnlich wie Altivec der G4s) erinnern, falls der Code SIMD fähig ist.

Habe mal heute versucht Altivec Code auf der Xbox zum Laufen zu bringen. Der Code wird zwar problemlos compiliert, die Ausführung bricht mit dem Fehler Illegal Expression ab, was laut www Recherche auf fehlende Altivec Unterstützung zurückzuführen. Zur VMX128 Einheit findet man nichts bis sehr wenig. D.h. irgendwelche Sample Codes oder Dokus habe ich nicht finden können. :|

Gruß
pajofego

Coda
2008-02-12, 00:48:13
IBM enhanced VMX for use in Xenon (Xbox 360) and called this enhancement VMX128. The enhancements comprise new routines targeted at gaming (accelerating 3D graphics and game physics)[2] and a total of 128 registers. VMX128 is not entirely compatible with VMX/Altivec, as a number of integer operations were removed to make space for the larger register file and additional application-specific operations.
Das sollte das Problem sein.