3.2 Heterogene Multi-Core-Architekturen: Cell BE Viele Rechenaufgaben können auf verschiedene CPUs und/oder Maschinen aufgeteilt und verteilt werden, um die Leistung zu steigern Herkömmliche CPUs und Techniken sind nicht ausreichend: CPUs in einer SMP Umgebung u.u. sehr teuer Zu große Platzverschwendung durch große Caches => kleiner Core, weniger GFLOPS/GOPS Zu viel Zeit wird beim Warten auf Daten aus dem Speicher verschwendet Cell verfolgt heterogenen Ansatz Verschiedene Prozessorarchitekturen auf einem Chip für Spezialaufgaben WS 2010/11, 7.12-16.12.2010 Folie 42
3.2 Heterogene Multi-Core-Architekturen: Cell BE Cell ist ein Prozessor Design ein Programmierparadigma Lt. eigener Angabe: revolutionäres neues Prozessor- Design: 1 Prozessoreinheit und bis zu 8 unabhängige SIMD- (Vektor) Prozessoren Nominell 150 GFLOPS möglich Keine On-Chip Caches auf den 8 SIMD-Prozessoren Verteilung von kleinen unabhängigen Tasks auf verschiedene SIMD-Prozessoren Ermöglicht massives paralleles Rechnen Im Prinzip: gesamter Vektorrechner auf einem Chip WS 2010/11, 7.12-16.12.2010 Folie 43
3.2 Heterogene Multi-Core-Architekturen: Cell BE Geschichte Entwicklung Cell Joint Venture von Sony, Toshiba und IBM (STI) Patent ausgestellt an Masakazu Suzuoki u. Takeshi Yamazaki (Sony) am 26.09.2002 an STI am 26.10.2004 Wird CPU für PlayStation3 IBM plante Produktion im ersten Halbjahr 2005 Erster Server und Workstations Ende 2005 von IBM Einsatz in HDTV Systeme von Sony und Toshiba seit 2006 Implementiert in 90 Nanometer Technologie seit 2007 in 65 nm Prototyp mit 234 Millionen Transistoren auf 221 mm² Vorgestellt 2005 auf der ISSCC (Int. Solid State Circuits Conference) WS 2010/11, 7.12-16.12.2010 Folie 44
3.2 Heterogene Multi-Core-Architekturen: Cell BE Chip und Layout WS 2010/11, 7.12-16.12.2010 Folie 45
3.2 Heterogene Multi-Core-Architekturen: Cell BE Aufbau Cell BE Architektur (grob) Power Processor Element (PPE) POWER Architecture Based L1 Cache L2 Cache DRAM SPE 1 SPE 5 MIC SPE 2 SPE 3 EIB SPE 6 SPE 7 SPE 4 SPE 8 BIC WS 2010/11, 7.12-16.12.2010 Folie 46
3.2 Heterogene Multi-Core-Architekturen: Cell BE Aufbau Cell BE Architektur (detaillierter) WS 2010/11, 7.12-16.12.2010 Folie 47
3.2 Heterogene Multi-Core-Architekturen: Cell BE Aufbau Cell BE Architektur 1 Power PC Processor Element (PPE) Kann 2 Threads gleichzeitig bearbeiten Beinhaltet 32 KB L1 Cache Enthält spezielle Vektoreinheit VMX/AltiVec 8 Vektorprozessoren: Synergistic Processor Elements (SPEs) Element Interface Bus (EIB) Besteht aus 4 x 16 Byte großen Datenringen Kann 96 Bytes/Zyklus übertragen WS 2010/11, 7.12-16.12.2010 Folie 48
3.2 Heterogene Multi-Core-Architekturen: Cell BE Dual Channel Memory Interface Controller (MIC) 12.8 GByte/s pro Kanal Gesamte Bandbreite 25.6 GBytes/s Ursprünglich nur anschließbar an Rambus Standard Seit PowerX8Cell auch DDR2-RAM möglich Dual Channel Bus Interface Controller (BIC) Insgesamt Bandbreite 76.8 GBytes/s 512 KB L2 Cache WS 2010/11, 7.12-16.12.2010 Folie 49
3.2 Heterogene Multi-Core-Architekturen: Cell BE PPE Power Processor Element WS 2010/11, 7.12-16.12.2010 Folie 50
3.2 Heterogene Multi-Core-Architekturen: Cell BE SPE - Vektor (oder SIMD) Prozessor WS 2010/11, 7.12-16.12.2010 Folie 51
3.2 Heterogene Multi-Core-Architekturen: Cell BE Unabhängige Verarbeitung SPEs sind keine Koprozessoren sondern unabhängige Einheiten SPEs führen eigenständige Programme aus Programme werden vom PPE in lokale Speicher der SPEs geladen Jede SPE Ausführungseinheit SPU bzw. SXU (SPE Execution Unit) operiert auf 128 Bitvektoren die aus vier 32 Bitelementen aufgebaut sein können Direkter Speicherzugriff über DMA Zentrale Kommunikationseinheit kann gleichzeitig zur SPU-Einheit laufen WS 2010/11, 7.12-16.12.2010 Folie 52
3.2 Heterogene Multi-Core-Architekturen: Cell BE SPE - Vektor (oder SIMD) Prozessor 256 KB lokaler SRAM 128 x 128 Bit Register 1 DMA Kontroller 1 Leitwerk 4 Fließkomma-Einheiten Gesamtleistung: 32 GFLOPS 4 Ganzzahlrechenwerke Gesamtleistung 32 GOPS WS 2010/11, 7.12-16.12.2010 Folie 53
3.2 Heterogene Multi-Core-Architekturen: Cell BE Programmierbeispiel: Hello - Cell Hauptprogramm auf PPE #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <libspe2.h> #include <pthread.h> extern spe_program_handle_t simple_spu; #define MAX_SPU_THREADS 16 void *ppu_pthread_function(void *arg){ spe_context_ptr_t ctx; unsigned int entry = SPE_DEFAULT_ENTRY; } ctx = *((spe_context_ptr_t *)arg); spe_context_run(ctx, &entry, 0, NULL, NULL, NULL) ; pthread_exit(null); WS 2010/11, 7.12-16.12.2010 Folie 54
3.2 Heterogene Multi-Core-Architekturen: Cell BE int main() { int i,spu_threads; spe_context_ptr_t ctxs[max_spu_threads]; pthread_t threads[max_spu_threads]; /* Determine the number of SPE threads to create */ spu_threads = spe_cpu_info_get(spe_count_usable_spes, -1); if (spu_threads > MAX_SPU_THREADS) spu_threads = MAX_SPU_THREADS; /* Create several SPE-threads to execute simple_spu */ for(i=0; i<spu_threads; i++) { /* Create context */ ctxs[i] = spe_context_create (0, NULL); /* Load program into context */ spe_program_load (ctxs[i],&simple_spu); } /* Create thread for each SPE context */ pthread_create (&threads[i],null,&ppu_pthread_function,&ctxs[i]) ; /* Wait for SPU-thread to complete execution. */ for (i=0; i<spu_threads; i++) pthread_join (threads[i], NULL) ; return (0); } WS 2010/11, 7.12-16.12.2010 Folie 55
3.2 Heterogene Multi-Core-Architekturen: Cell BE Programm auf SPE simple_spu.c #include <stdio.h> int main(unsigned long long id) { /* The first parameter of an spu program will always be the spe_id of the spe thread that issued it. */ printf("hello Cell (0x%llx)\n", id); return 0; } WS 2010/11, 7.12-16.12.2010 Folie 56
3.3 GPGPUs Eine kurze Geschichte der Grafikkarten ursprünglich: Graphics Card steuert Monitor an Mitte 80er: Grafikkarten mit 2D-Beschleunigung angelehnt an Arcade- und Home-Computer frühe 90er: erste 3D-Beschleunigung: Matrox Mystique, 3dfx Voodoo Rastern von Polygonen WS 2010/11, 7.12-16.12.2010 Folie 57
3.3 GPGPUs Eine kurze Geschichte der Graphikkarten ursprünglich keine einheitliche Programmierschnittstelle herstellerspezifische Lösungen (3dfx Glide bzw. Matrox Simple Interface) Anfang der 90er: OpenGL etabliert in professionellem Umfeld Microsofts Direct3D zunächst unterlegen gewinnt Marktanteile dank häufiger Verbesserungen Ende der 90er: Grafikkarten übernehmen Koordinaten-Transformation und Beleuchtung (z.b. NVIDIA GeForce 256) Begriff Graphics Processing Unit wird erfunden WS 2010/11, 7.12-16.12.2010 Folie 58
3.3 GPGPUs Beispiel: Direct3D 10 Pipeline WS 2010/11, 7.12-16.12.2010 Folie 59
3.3 GPGPUs 2000er: zunächst nur Fixed-Function-Pipeline (FFP) Shader-Programme bieten mehr Flexibilität als FFP Pixel-Shader modellieren Oberflächen Vertex-Shader modifizieren Gitterpunkte Shader-Programme ursprünglich nur einfache Listen 2002: ATI Radeon 9700 kann Loops in Shadern ausführen Heute: Shader turing-vollständig Hersteller: ATI und NVIDIA Massenmarkt niedrige Preise WS 2010/11, 7.12-16.12.2010 Folie 60
3.3 GPGPUs GPGPUs GPGPU = General Purpose Graphics Processing Unit Grafikkarten zunehmend flexibler programmierbar stetig wachsende Leistung geeignet für Streamprozessing geringes Verhältnis IO-zu-Rechenlast Datenparallelität (SIMD-Verarbeitung) Ausrichtung auf Spiele: single precision wichtiger als double precision WS 2010/11, 7.12-16.12.2010 Folie 61
3.3 GPGPUs Aufbau GPGPU WS 2010/11, 7.12-16.12.2010 Folie 62
3.3 GPGPUs Eigenschaften von GPGPUs viele, aber einfache Cores keine Sprungvorhersage etc. gruppiert in Multi-Prozessoren (Vektorprozessoren) Probleme bei nicht einheitlichen Sprüngen viele Register großer globaler Speicher Bandbreite: >100 GB/s Latenz: ~400 Taktzyklen kleine, schnelle on-chip Shared-Memory-Blöcke WS 2010/11, 7.12-16.12.2010 Folie 63
3.3 GPGPUs GPGPU: GeForce 8080 WS 2010/11, 7.12-16.12.2010 Folie 64
3.3 GPGPUs Programmierung sehr viele Threads kurzlebige Threads da geringer Overhead viele Threads um Latenz vom Speicher zu verdecken Threads werden in Blöcken gruppiert Blöcke werden auf Multi-Prozessoren verteilt Standards: CUDA (NVIDIA, Marktführer) OpenCL (offener Standard, entsprechend zu OpenGL) FireStream (AMD) DirectCompute (Microsoft) WS 2010/11, 7.12-16.12.2010 Folie 65
CUDA Programmierung in C Function-Offloading: einzelne Funktionen laufen auf GPGPU (Kernels) spezieller Compiler (nvcc) separiert Code drei Funktionstypen: host laufen auf CPU device laufen auf GPGPU global laufen auf GPGPU (können aber nur von CPU aufgerufen werden) drei Speichertypen: normaler Speicher im CPU-RAM device im RAM der GPGPU shared im Shared-Memory auf den Multi-Prozessoren WS 2010/11, 7.12-16.12.2010 Folie 66
Cuda Memory Management CUDA-API-Aufrufe: Allokation/Deallokation von GPGPU-RAM Transfer CPU-RAM <-> GPGPU-RAM Kernels: Transfer GPGPU-RAM <-> Shared-Memory Spezielle Speicherbereiche: Konstanten Texturen (verschiedene Adressierungen) WS 2010/11, 7.12-16.12.2010 Folie 67
CUDA: Hello World WS 2010/11, 7.12-16.12.2010 Folie 68
CUDA: Hello World: WS 2010/11, 7.12-16.12.2010 Folie 69
CUDA: Vektor-Addition res = a + x b WS 2010/11, 7.12-16.12.2010 Folie 70
CUDA: Vektor-Addition WS 2010/11, 7.12-16.12.2010 Folie 71
Hardware-Details: NVIDIA vs. ATI WS 2010/11, 7.12-16.12.2010 Folie 72
Hardware-Details Thread-Scheduling Speicherzugriff Beispiel: Matrix-Multiplikation WS 2010/11, 7.12-16.12.2010 Folie 73
Hardware-Details: NVIDIA G80 WS 2010/11, 7.12-16.12.2010 Folie 74
Hardware-Details: NVIDIA G80 NVIDIA G80 Multiprozessor Vektorprozessor beinhaltet: 8 Shader: Single-Precision-Float- und Integer-Rechenwerk 1 Double Precision Unit (DPU) 2 Special Function Units (SFU) Sinus etc. 4096 Register 16 KB Shared Memory WS 2010/11, 7.12-16.12.2010 Folie 75
Hardware-Details: AMD Radeon HD 5970 SIMD-Engine (links) beinhaltet 16 VLIW-Units (rechts) WS 2010/11, 7.12-16.12.2010 Folie 76
Hardware-Details: AMD Radeon HD 5970 Multiprozessor AMD Nomenklatur: SIMD-Engine beinhaltet 16 Thread-Prozessoren 5-fach VLIW-Design 4 normale Pipelines Single-Precision-Float- und Integer-Rechenwerk Eine erweiterte Pipeline Double-Precision und spezielle Funktionen. Register WS 2010/11, 7.12-16.12.2010 Folie 77
Hardware-Details: AMD Radeon HD 6970 Multiprozessor AMD Nomenklatur: SIMD-Engine beinhaltet 16 Thread-Prozessoren 4-fach VLIW-Design 4 normale Pipelines Double-Precision-Leistung ¼ der Single-Precision-Leistung Register WS 2010/11, 7.12-16.12.2010 Folie 78
Hardware-Details: AMD Radeon HD 6970 4-fach VLIW-Design (Gegensatz zum alten 5-fach Design) WS 2010/11, 7.12-16.12.2010 Folie 79
Hardware-Details: AMD Radeon HD 6970 SIMD Engines beinhalten je 16 VLIW Units L1/L2-Caches deutlich kleiner als bei NVIDIA Caches sind read-only dafür deutlich mehr ALUs als bei NVIDIA WS 2010/11, 7.12-16.12.2010 Folie 80
Hardware-Details: AMD Radeon HD 6970 WS 2010/11, 7.12-16.12.2010 Folie 81
Hardware-Details: NVIDIA GT100 WS 2010/11, 7.12-16.12.2010 Folie 82
Hardware-Details: NVIDIA GT100 (a.k.a. Fermi) Vektorprozessor, beinhaltet: 32 Shader: Integer-Rechenwerk und Single-Precision-Float oder Double Precision mit halber Geschwindigkeit 16 Load-/Store-Units 4 Special Function Units (SFU) Sinus etc. 64 KB Shared Memory/Cache 32k Register WS 2010/11, 7.12-16.12.2010 Folie 83
NVIDIA Fermi WS 2010/11, 7.12-16.12.2010 Folie 84
Speicherhierarchie: Register (am schnellsten) Shared Memory/L1 Cache entweder 16kB Cache und 48kB SM Oder 48 kb Cache und 16kB SM L2 Cache 768kB ca. 260GB/s Bandbreite DRAM 1-6 GB ca. 130GB/s Bandbreite Latenz ca. 400 Takte WS 2010/11, 7.12-16.12.2010 Folie 85
Thread-Scheduling: Kernel = Funktion auf Grafikkarte viele Threads um Parallelität der GPGPU zu nutzen und Speicherlatenz zu verdecken Threads gruppiert in Blöcken Thread-Blöcke gruppiert in Grid Grid und Blöcke können 1D bis 3D sein Thread-IDs: Koordinaten blockidx, threadidx. WS 2010/11, 7.12-16.12.2010 Folie 86
Thread-Scheduling: Thread-Blöcke werden auf Multiprozessoren verteilt Multiprozessoren brechen Blöcke in Warps auf Warps = kleinere Thread-Gruppen (meist 32 Threads) Warps bestehen aus zwei Half-Warps alle Threads eines Warps: quasi-parallele Ausführung Problem bei divergenten Branches: serielle Abarbeitung WS 2010/11, 7.12-16.12.2010 Folie 87
Thread-Scheduling Problem-Zerlegung: viele Blöcke alle Multiprozessoren beschäftigt viele Threads je Block Speicherlatenz verdecken aber: je weniger Threads je Block, desto mehr Shared Memory je Thread verfügbar Daumenregel: doppelt so viele Blöcke wie Multiprozessoren 256 Threads je Block Praxis: viel Experimentieren notwendig um optimale Aufteilung zu finden WS 2010/11, 7.12-16.12.2010 Folie 88
3 3. Architektur von Hochleistungsprozessoren Speicherzugriff Thread mit Nummer x im Warp Aligned: Thread x greift auf Adresse 128 k + 4 x zu Coalescing: Alle Zugriffe eines Warps können in eine Transaktion von 128 Byte zusammengefasst werden Coalescing bringt beste Performance, benötigt meist Alignment alte GPUs (Compute Capability 1.0 bzw. 1.1) ineffizienter als neue (Compute Capability 1.2) Bei Schreiben auf selbe Adresse: Warp Serialize (serielle Ausführung) WS 2010/11, 7.12-16.12.2010 Folie 89
Speicherzugriff: Coalescing, Compute Capability 1.1 k-ter Thread greift auf k-tes Wort in 128-Byte-Segment zu, nicht alle Threads müssen teilnehmen. OK, 1 Transaktion: Out of Sequence, 16 Transaktionen: Misaligned, 16 Transaktionen: WS 2010/11, 7.12-16.12.2010 Folie 90
Speicherzugriff: Coalescing, Compute Capability 1.2 Transaktionen können 32, 64 oder 128 Byte groß sein, kleinere Transaktionen um Bandbreite zu sparen. 1 Transaktion, 64 Byte: 2 Transaktionen, 64 bzw. 32 Byte: 1 Transaktion, 128 Byte: WS 2010/11, 7.12-16.12.2010 Folie 91
Speicherzugriff Kopiert Vector src nach dst Offset verschiebt Alignment bei falschem Alignment kein Coalescing daher schlechter Durchsatz WS 2010/11, 7.12-16.12.2010 Folie 92
WS 2010/11, 7.12-16.12.2010 Folie 93
Legende: Rot: GeForce GTS 250 (älteres Modell) sehr anfällig für falsches Alignment, Grün: NVIDIA Tesla C1060 weniger anfällig, dennoch Einbruch auf 65% Blau: Testla C2050 kaum abhängig vom Alignment, dank Caches WS 2010/11, 7.12-16.12.2010 Folie 94
Beispiel: Matrix-Multiplikation Scheinbar einfache Aufgabe, häufig Teilproblem beim wissenschaftlichen Rechnen Beispiele: Computergrafik Optik Matrizenmechanik Schwierigkeit: wenig Berechnung aber viel Speicherzugriff Ziel: Speicherzugriffe so organisieren, dass maximale Bandbreite erreicht wird. WS 2010/11, 7.12-16.12.2010 Folie 95
Beispiel: Matrix-Multiplikation Folgende Beispiele: Multiplikation von float-matrizen Dimension: 1024 x 1024 gemessene Zeiten gelten für eine Matrix-Multiplikation Hardware: NVIDIA GeForce GTS 250 Performance-Unterschiede: 2 Größenordnungen WS 2010/11, 7.12-16.12.2010 Folie 96
Matrix-Multiplikation: naiver Algorithmus Zeit: 1.032s Probleme: Matrizen werden mehrfach ausgelesen kaum Coalescing beim Speicherzugriff WS 2010/11, 7.12-16.12.2010 Folie 97
Matrix-Multiplikation: transponiert Erwartung: Matrix B ist transponiert gegeben Zeit: 1.415s ~40% langsamer Gegensatz: CPUs sind mit diesem Algorithmus schneller WS 2010/11, 7.12-16.12.2010 Folie 98
Matrix-Multiplikation: Texture Caching Matrizen A und B über Texture-Units lesen (Caching), Zeit: 0.046s, ~20 schneller. Problem: Textur-Caches haben begrenzte Größe, daher werden nicht alle Zugriffe gecachet. WS 2010/11, 7.12-16.12.2010 Folie 99
Matrix-Multiplikation: Shared Memory WS 2010/11, 7.12-16.12.2010 Folie 100
Matrix-Multiplikation: Shared Memory Matrizen kachelweise lesen/schreiben on-chip Shared Memory dient als schneller Puffer Synchronisation wichtig Schleife: Beide Kacheln lesen Synchronisation Kachelstreifen multiplizieren Synchronisation Zeit: 0.018s ~55 x schneller Problem: Bank Conflicts bei Shared Memory WS 2010/11, 7.12-16.12.2010 Folie 101
Zusammenfassung GPGPUs haben viele, aber einfach gestaltete Cores Programmierung mittels Function-Offloading sehr viele Threads wegen Parallelität und Latenz vom GPGPU-RAM Threads sind in Blöcken zusammengefasst Blöcke sind im Grid zusammengefasst on-chip Shared Memory dient als schneller Zwischenspeicher Transfer CPU-RAM zu GPGPU-RAM via API-Funktionen WS 2010/11, 7.12-16.12.2010 Folie 102