Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Blowfish mit CUDA Dominik Oepen 22.07.2008. Inhalt ● Blowfish Grundlagen ● Implementierungsdetails ● Performance ● Fazit.

Ähnliche Präsentationen


Präsentation zum Thema: "Blowfish mit CUDA Dominik Oepen 22.07.2008. Inhalt ● Blowfish Grundlagen ● Implementierungsdetails ● Performance ● Fazit."—  Präsentation transkript:

1 Blowfish mit CUDA Dominik Oepen

2 Inhalt ● Blowfish Grundlagen ● Implementierungsdetails ● Performance ● Fazit

3 Blowfish Basics

4 Was ist eine Blockchiffre ● Eingabestrom wird in gleich große Blöcke zerlegt ● Blöcke werden einzeln ver-/entschlüsselt

5 Funktionsweise Blowfish ● S-Boxen: 4 Arrays mit jeweils Bit integer Werten ● P-Array: 18 konstante 32 Bit Werte ● P und S Boxen werden mit verwendetem Schlüssel verknüpft ● Permutationen, etc. in Abhängigkeit von den Boxen

6 Modi für Blockchiffren ● ECB ● CBC ● OFB ●... ● Key diversity: Schlüssel wird für jeden Block mit Blockindex per XOR verknüpft => anderer Schlüssel für jeden Block, weiterhin parallelisierbar

7 Implementierte Modi ● ECB ● Key diversyity ● Key diversity hat extremen Speicherbedarf: 1024 mal so viel Speicher für S-Boxen wie für Input => geringer Grad an Multiprogramming => CUDA Implementierung bringt kaum Vorteile

8 Implementationsdetails

9 Programmablauf ● Lade Daten in GPU Speicher ● Initialisiere S-Boxen und P-Array im globalen Grafikkartenspeicher ● Jeder Thread verschlüsselt einen Block (64 Bit) ● Mehrere Durchläufe des Kernels mit fester Anzahl an Threads ● Kopiere verschlüsselte Daten zum Host

10 Speicheraufteilung - ECB ● S-Boxen verknüpft mit Schlüssel im globalen Speicher der Grafikkarte ● __device__ > Blowfish_Init ● Nicht parallelisiert (Race conditions möglich), aber nur geringer Aufwand ● Jeder Thread verschlüsselt einen Block (2 uint32_t Werte => 64 Bit)

11 Speicheraufteilung – ECB optimiert ● Eine Kopie der S-Boxen in shared Memory pro Block ● CUDA Block Größe: 256 Threads/Block => jeder Thread kopiert einen Wert der S-Boxen ● Zu verschlüsselnde Daten werden in den lokalen Speicher der Threads kopiert. ● Nach Verschlüsselung kopieren der Ergebnisse in globalen Grafikkartenspeicher, von dort zum Host

12 Quellcode ● Blowfish-cuda.cu enthält Host Programm mit kernel Aufrufen ● blowfish-kernel.cu enthält Kernel und device Funktionen

13 Performance Messungen

14 Verwendete Plattform ● Intel Core 2 Duo 8400 (3 GHz, 4 MB Cache) ● 4 GByte DDR2-800 RAM ● Ubuntu 8.04 (64 Bit), Kernel ● CUDA 2.0 Beta ● NVIDIA Treiber

15 Methode ● Gemessen wurde die Verschlüsselung von einer 50 einer 100, einer 200 und einer 300 MByte großen Datei ● Es wird nur die Rechenzeit (ohne I/O) gemessen, mittels gettimeofday => mikrosekunden Auflösung ● Erwartung: CUDA Implementierung lohnt sich erst bei großen Dateien

16 Vergleich der Varianten

17 ● CUDA ohne shared memory => Speedup von ungefähr 2 gegenüber Pthreads ● CUDA mit shared memory => Speedup von ungefähr 3 gegenüber Pthreads ● Shared memory => Speedup von ca. 0,5

18 ECB mit shared memory

19 Vergleich mit OpenSSL ● CUDA nur minimal schneller als OpenSSL ● CUDA 4096 Threads vs. OpenSSL 0.9.8g: 2,9s vs 3,2s Gemessen mit time, inklusive I/O, stark schwankende Ergebnisse

20 Analyse mit CUDA Visual Profiler

21 ● Shared memory ist static ● Großteil der Speicherzugriffe ist “uncoalesced” => Serialisierung der Threads => großes Optimierungspotential ● GPU ist komplett ausgelastet (ohne shared memory nur Auslastung von 0,33) ● Siehe Analyse.csv

22 Verschmolzene Speicherzugriffe ● The simultaneous global memory accesses by each thread of a half- warp (16 threads on G80) during the execution of a single read or write instruction will be coalesced into a single access if: – The size of the memory element accessed by each thread is either 4, 8, or 16 bytes – The elements form a contiguous block of memory – The Nth element is accessed by the Nth thread in the half-warp – The address of the first element is aligned to 16 times the element’s size

23 Globale Speicherzugriffe __shared__ uint32_t shared_S[4][256]; shared_S[0][threadIndex] = ctx_S[0][threadIndex]; shared_S[1][threadIndex] = ctx_S[1][threadIndex]; shared_S[2][threadIndex] = ctx_S[2][threadIndex]; shared_S[3][threadIndex] = ctx_S[3][threadIndex]; In __global__ void Blowfish_Encrypt256: In __device__ void do_decryption: Xl = data[index]; Xr = data[index + 1];... data[index] = Xl; data[index + 1] = Xr;

24 Optimierungsmöglichkeiten ● Daten in Texturspeicher laden ● Daten für jeden Block in shared Memory laden ● Vor dem Zurückschreiben der Daten __synchthreads() für verschmolzenen Speicherzugriff

25 Fazit ● Grundsätzlich ist es recht einfach ein CUDA Programm zu schreiben ● Debugging ist schwierig (keine Host Funktionen, Emulationsmodus liefert teilweise andere Ergebnisse als reale Ausführung) ● Optimierung ist schwierig, CudaVisualProfiler ist ein gutes Werkzeug um Bottlenecks zu finden ● Hauptschwierigkeit: Organisation des Speichers (in meinem Fall)

26 Verwendete Quellen ● CUDA Programming Guide: CUDA_Programming_Guide_1.1.pdf CUDA_Programming_Guide_1.1.pdf ● General Purpose Computation on the GPU: ● CUDA Tutorial: A_Tutorial_No_NDA_Apr08.pdf A_Tutorial_No_NDA_Apr08.pdf ● GPGPU Course:


Herunterladen ppt "Blowfish mit CUDA Dominik Oepen 22.07.2008. Inhalt ● Blowfish Grundlagen ● Implementierungsdetails ● Performance ● Fazit."

Ähnliche Präsentationen


Google-Anzeigen