College 10: OpenCL (1)

Vergelijkbare documenten
Concurrency. Gerard Tel / Jacco Bikker - november 2015 januari Welkom!

Concurrency. Gerard Tel / Jacco Bikker - november 2017 februari College 8: Patronen. Welkom!

College 11: OpenCL (2)

Concurrency. Gerard Tel / Jacco Bikker - november 2015 januari Welkom!

College 13: Patterns (2)

college 2: Introductie

Concurrency. Gerard Tel / Jacco Bikker - november 2015 januari Welkom!

Concurrency. Gerard Tel / Jacco Bikker - november 2015 januari Welkom!

College 4: Mechanismen

College 15: Monte-Carlo

Concurrency. Gerard Tel / Jacco Bikker - november 2015 januari Welkom!

Concurrency. Gerard Tel / Jacco Bikker - november 2015 januari Welkom!

Centrale begrippen hoofdstuk 3. Waarom multiprogramming? Vandaag. processen proces state: running, ready, blocked,... Vragen??

Computerarchitectuur. Terugblik / discussie / oefenopgaven

Computerarchitectuur. Ch 4. Data-Level Parallelism

Computerarchitectuur. Ch 4. Data-Level Parallelism

Tentamen Programmeren in C (EE1400)

Universiteit van Amsterdam FNWI. Voorbeeld van tussentoets Inleiding programmeren

HOGESCHOOL VAN AMSTERDAM Informatica Opleiding. CPP 1 van 10

College 17: Monte-Carlo

Kompas. zijn klasse. protected override void OnDraw(Canvas canv) { base.ondraw(canv);

Uitwerking oefententamen Computerarchitectuur December 2016

Vakgroep CW KAHO Sint-Lieven

Tentamen Computersystemen

High Performance Computing

PyCuda. oftewel massief parallel rekenen. Jasper Spaans, Fox-IT PUN meeting

Real-Time Software (RTSOF) EVMINX9 Week 2

De Parallelle Revolutie van GPU's en CPU's

Tweede Toets Concurrency 2 februari 2017, , Educ-β.

informatica. hardware. overzicht. moederbord CPU RAM GPU architectuur (vwo)

n-queens minimale dominantie verzamelingen Chessboard Domination on Programmable Graphics Hardware door Nathan Cournik

Instructies en blokken

Overerving & Polymorfisme

Tentamen Programmeren in C (EE1400)

Dergelijke functionaliteit kunnen we zelf ook aan eigen code toevoegen.


Multi-core systemen. door Alexander Melchior

Datastructuren: stapels, rijen en binaire bomen

Datastructuren Werkcollege Intro

Programmeren in Java 3

Toetsbundel Deel 2 Concurrency 8 oktober 2018, Gerard Tel, Niet verspreiden 1!.

Debugging in embedded en native systemen met GDB

Elementary Data Structures 3

HPC CLOUD INTRODUCTIE. Jan Bot, SURFsara 5 augustus 2015

Het begrip 'Proces' Proces-toestand

Beter, Sneller, Mooier. Processoren 12 januari 2015

Wat is FP? The Haskell School of Expression. Functies. Types 1+1=2. Iedere expressie (en waarde) heeft een type.

De MySQL C API. Variabelen in C Functies in C Pointers in C

GPU versus CPU. Renderen terwijl uw processor stil staat? SketchUp Pro. Octane Render

Hoe werkt een computer precies?

Computerarchitectuur. Hoofdstuk 3: Instruction-Level Parallelism

Gelijktijdigheid: Wederzijdse Uitsluiting & Synchronisatie Concurrency: Mutual Exclusion & Synchonization (5e ed: , Appendix A.

Tweede deeltentamen Mobiel programmeren - versie 1 Vrijdag 2 februari 2018, uur

import java.io.*; één klasse public class Hallo { public static void main (String[] a) ...met één functie System.out.println("Hallo!

Lessen Java: Reeks pag. 1

Hoofdstuk 7. Computerarchitectuur

3 e jaars GameTech student C++ voor hobby, eerste programmeertaal Assistent bij een heleboel vakken

Real-Time Systems (RTSYST)

College 11: Game Engines

Aanvullende toets Gameprogrammeren (INFOB1GP) Woensdag 24 december 2014, uur

Tentamen Computersystemen

Modelleren en Programmeren

Een gelinkte lijst in C#

ALGORITMIEK: answers exercise class 7

Objectgericht programmeren 1.

Toets In2305-ii Embedded Programming Dinsdag 28 November 2006, 15:45-16:30

wat is er nodig om een ISensorEventListener te zijn?

Stacks and queues. Introductie 45. Leerkern 45. Terugkoppeling 49. Uitwerking van de opgaven 49

Modelleren en Programmeren

Deel 1: schriftelijk deel

Een.NET-besturingssysteemtoolkit. Discovering Cosmos. Sijmen J. Mulder

Van Poort tot Pipeline. Ben Bruidegom & Wouter Koolen-Wijkstra AMSTEL Instituut Universiteit van Amsterdam

Computerarchitectuur 2016 Inleveropdracht 3: Exploiting Memory Hierarchies in Modern Systems

C++ programmeermethoden Bachelor Kunstmatige Intelligentie

Hoofdstuk 3: Processen: Beschrijving en Besturing. Wat is een proces? Waarom processen? Wat moet het OS ervoor doen? Is het OS zelf een proces?

Hertentamen 8D040 - Basis beeldverwerking

int main() { int m; m = power(2,3) /* berekent 2^3 en geeft de resultaat naar m terug */ }

public boolean equaldates() post: returns true iff there if the list contains at least two BirthDay objects with the same daynumber

Java Programma structuur

EE1400: Programmeren in C BSc. EE, 1e jaar, , 4e college

Voorbeeld: Simulatie van bewegende deeltjes

public boolean egualdates() post: returns true i f f there i f the l i s t contains at least two BirthDay objects with the same daynumber

Introductie in C++ Jan van Rijn. September 2013

Tentamen Objectgeorienteerd Programmeren TI februari Afdeling ST Faculteit EWI TU Delft

Uitwerking Tweede deeltentamen Imperatief programmeren - versie 1 Vrijdag 21 oktober 2016, uur

Modelleren en Programmeren

Jeroen uit. Extra informatie. Voor de lunch. Arduino zo aangesloten om mijn code te laten werken. (versie voor lunch) (code voor de lunch)

Nederlandse samenvatting (Dutch summary)

Digitale en analoge technieken

Inleiding C++ Coding Conventions

HPC CLOUD INTRODUCTIE. Jan$Bot,$SURFsara$ 15$oktober$2015$

Syntax van opdracht. opdracht. expressie. variabele. = expressie ; klasse naam. methode naam. property naam += object

public Bier ( string N, double P, Brouwerij B) { Naam = N; AlcoholPerc = P; Brouwer = B;

Go: een snelle introductie

Uitwerking Aanvullend tentamen Imperatief programmeren Woensdag 24 december 2014, uur

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE

Instructies en blokken

Tentamen Object Georiënteerd Programmeren TI oktober 2014, Afdeling SCT, Faculteit EWI, TU Delft

Modelleren en Programmeren

Transcriptie:

Concurrency Gerard Tel / Jacco Bikker - november 2017 februari 2018 College 10: OpenCL (1) Welkom!

Previously in Concurrency

Concurrency College 8 Patronen 3 SIMD System.Numerics.Vectors namespace System.Numerics { public struct Vector3 : IEquatable<Vector3>, IFormattable { public float X; public float Y; public float Z; public Vector3(float value); public Vector3(Vector2 value, float z); public Vector3(float x, float y, float z); public static Vector3 operator -(Vector3 value); public static Vector3 operator -(Vector3 left, Vector3 right); public static bool operator!=(vector3 left, Vector3 right); public static Vector3 operator *(float left, Vector3 right); public static Vector3 operator *(Vector3 left, float right); public static Vector3 operator *(Vector3 left, Vector3 right); public static Vector3 operator /(Vector3 value1, float value2); public static Vector3 operator /(Vector3 left, Vector3 right); public static Vector3 operator +(Vector3 left, Vector3 right); public static bool operator ==(Vector3 left, Vector3 right);

Concurrency College 8 Patronen 4 SIMD System.Numerics.Vectors Voorbeeld: C# code: Vector3 D = Vector3.Normalize( T - P ); Assembler: vsubps xmm0,xmm1,xmm6 ; subtract vmovaps xmm1,xmm0 vdpps xmm1,xmm1,xmm0,0f1h ; dot vcvtss2sd xmm1,xmm1,xmm1 ; float to double vsqrtsd xmm1,xmm0,xmm1 ; square root vcvtsd2ss xmm1,xmm1,xmm1 ; double to float vmovupd xmmword ptr [rsp+40h],xmm0 vmovss xmm0,dword ptr [7FE90EEA518h] vdivss xmm0,xmm0,xmm1 ; division...

Concurrency College 8 Patronen 5 SIMD Klaar? Nee. Vector3 D = Vector3.Normalize( T - P ); Vector3 A = T P // 75% float B = dot( A, A ) // 75% Vector3 C = { B, B, B } // 75% Vector3 D = A / C // 75%

Concurrency College 8 Patronen 6 SIMD Scalar Flow Vector3 D = Vector3.Normalize( T - P ); Wat gebeurt hier nu eigenlijk echt? Vector3 d = T P; float dot = d.x * d.x + d.y * d.y + d.z * d.z; float length = sqrt( dot ); d /= length; D = D;

Concurrency College 8 Patronen 7 SIMD Scalar Flow Vector3 D = Vector3.Normalize( T - P ); Wat gebeurt hier nu eigenlijk echt? float dx = T.x P.x; float dy = T.y P.y; float dz = T.z P.z; float dot = d.x * d.x; float v1 = d.y * d.y; float v2 = d.z * d.z; dot += v1; dot += v2; float length = sqrt( dot ); D.x = dx / length; D.y = dy / length; D.z = dz / length; Scalar flow: Het programma, teruggebracht tot de kleinste elementen, waarbij elke berekening een of twee operanden transformeert in een resultaat.

Concurrency College 8 Patronen 8 SIMD Scalar Flow Vector3 D = Vector3.Normalize( T - P ); Vectorizatie: Optimaal normaliseren met SIMD: input is 4x T, 4x P opgedeeld in componenten: Tx4, Ty4, Tz4 en Px4, Py4, Pz4 output is 4x D: Dx4, Dy4, Dz4 float dx = T.x P.x; float dy = T.y P.y; float dz = T.z P.z; float dot = d.x * d.x; float v1 = d.y * d.y; float v2 = d.z * d.z; dot += v1; dot += v2; float length = sqrt( dot ); D.x = dx / length; D.y = dy / length; D.z = dz / length; float4 dx4 = sub4( Tx4, Px4 ); float4 dy4 = sub4( Ty4, Py4 ); float4 dz4 = sub4( Tz4, Pz4 ); float4 dot4 = mul4( dx4, dx4 ); float4 v1 = mul4( dy4, dy4 ); float4 v2 = mul4( dz4, dz4 ); dot4 = add4( dot4, v1 ); dot4 = add4( dot4, v2 ); float4 length4 = sqrt4( dot4 ); Dx4 = div4( dx4 / length4 ); Dy4 = div4( dy4 / length4 ); Dz4 = div4( dz4 / length4 );

Concurrency College 8 Patronen 9 SIMD SIMD Data class Particle { Vector3 position; Vector3 velocity; float mass; } Particle p[1024]; Optimaal normaliseren met SIMD: input is 4x T, 4x P opgedeeld in componenten: Tx4, Ty4, Tz4 en Px4, Py4, Pz4 output is 4x D: Dx4, Dy4, Dz4 = AoS Array of Structures Structure of Arrays SoA float px[1024]; float py[1024]; float pz[1024]; float vx[1024]; float vy[1024]; float vz[1024]; float mass[1024]; Vector4 px4[256]; Vector4 py4[256]; Vector4 pz4[256]; Vector4 vx4[256]; Vector4 vy4[256]; Vector4 vz4[256]; Vector4 mass4[256];

Concurrency College 8 Patronen 10 SIMD Vectorization Digest: Vectorizatie begint met het identificeren van een scalar flow. Uitgevoerd met vector artithmetic voeren we 4 onafhankelijke, identieke flows in parallel uit. De data moet passend zijn voor de vector flow: waar we eerst pos.x gebruiken, gebruiken we nu pos.x4 (en dus niet pos.xyzw!), waar we eerst de constante PI gebruiken, gebruiken we nu { PI, PI, PI, PI }. We noemen deze data layout struct of arrays. Theoretische winst is 4x. Maar: Er is bijna altijd sprake van enige overhead om data in het juiste formaat te krijgen. De C# JIT compiler is niet optimaal.

Concurrency College 8 Patronen 11 SIMD SIMD en Control Flow Wat doen we wanneer niet alle lanes hetzelfde willen?? A B

Concurrency College 8 Patronen 12 SIMD

Agenda: Introductie OpenCL OpenCL / C# Workgroups Tot Slot

Concurrency College 10 OpenCL (1) 14 Introductie Heterogene Systemen Een modern system heeft naast 1 (of 2) CPUs een grafische co-processor: de GPU.

Concurrency College 10 OpenCL (1) 15 Introductie AMD: RX Vega 64 631 NVidia: GTX1080Ti 709 Intel: i9-7980xe 1899 Xeon Phi 7120P 3167 484 GB/s 13.7 TFLOPS 320 GB/s 11.3 TFLOPS 50 GB/s 1.1 TFLOPS 352 GB/s ~6 TFLOPS

Concurrency College 10 OpenCL (1) 16 Introductie Heterogene Systemen Een modern system heeft naast 1 (of 2) CPUs een grafische co-processor: de GPU. GPU: veel rekenkracht: >10 Tflops (i9: ~1 Tflops) veel bandbreedte: 512GB/s (i9: 50GB/s)

Concurrency College 10 OpenCL (1) 17 Introductie GPU Performance Rekenkracht: Beperkt executiemodel 32-wide SIMT Bandbreedte: Streaming executiemodel Expliciete geheugenarchitectuur

Concurrency College 10 OpenCL (1) 18 Introductie Beperkt Executiemodel Geen branch prediction Een taak tegelijk Geen context switching Beperkte super-scalar pipeline Geen out-of-order execution En: Lage kloksnelheid (~1Ghz)

Concurrency College 10 OpenCL (1) 19 Introductie GPU: Massively Parallel Een GPU bestaat uit: * 24 Shading Multiprocessors Per SM: 128 CUDA cores (4 groepen van 32) Totaal: 3072 CUDA cores. Eén SM kan maximaal 2048 threads uitvoeren: 16 per CUDA core. Het mechanisme wat hier voor gebruikt wordt lijkt op hyperthreading. Het maximale aantal threads is dus 49.152. * Titan X / Maxwell architectuur

Concurrency College 10 OpenCL (1) 20 Introductie Beperkt Executiemodel Een GPU groepeert de threads in warps van 32 threads, en voert deze uit met SIMT: Single Instruction, Multiple Thread Een GPU is dus eigenlijk een 32-wide vector machine.

Concurrency College 10 OpenCL (1) 21 Introductie GPGPU Samenvatting: Tienduizenden threads In groepen van 32 Een GPU is ongeschikt voor taak-parallellisme. Een GPU is zeer geschikt voor data parallellisme, maar: alleen wanneer de parallelle taken een identieke flow hebben.

Concurrency College 10 OpenCL (1) 22 Introductie GPGPU CPU GPU

Concurrency College 10 OpenCL (1) 23 If you were plowing a field, which would you rather use? Two strong oxen, or 1024 chickens? - Seymour Cray

Concurrency College 10 OpenCL (1) 24 Introductie Heterogene Systemen In een heterogeen systeem kan een applicatie zowel de CPU als de GPU benutten. Doel: data-parallelle taken uitvoeren op de GPU; taak-parallel werk en serieel werk op de CPU. De GPU is dus géén vervanging voor de CPU.

Agenda: Introductie OpenCL OpenCL / C# Workgroups Tot Slot

Concurrency College 10 OpenCL (1) 26 OpenCL OpenCL Standaard Framework voor het ontwikkelen van software die uitgevoerd kan worden op heterogene platformen, bestaande uit CPUs, GPUs, DSPs, FPGAs en andere processoren. Computing System Compute Devices Compute Units Processing Elements OpenCL Memory Hierarchy: Global memory Read-only memory Local memory Per-element private memory CPU Cores SIMD Lanes GPU SMs CUDA cores

Concurrency College 10 OpenCL (1) 27 OpenCL OpenCL Standaard Het OpenCL executiemodel is fundamenteel parallel, en gaat uit van regular parallelism: meerdere processing elements voeren dezelfde code uit: een kernel.

Concurrency College 10 OpenCL (1) 28 OpenCL Kernel #define C(p) min(1.,sqrt(10.*abs(length(p-.5)-.4))) #define D(p,o) ((d=length(p-o)*5.)<=.6? d:1.) void mainimage( out vec4 O, in vec2 pos ) { vec2 res = iresolution.xy; vec2 C = vec2( 0.5, 0.5 ); vec2 d = pos / res - C; if (length( d ) <.2) O.xyz = vec3( 1, 0, 0 ); else O.xyz = vec3( 0, 0, 0 ); }

Concurrency College 10 OpenCL (1) 29 OpenCL Kernel https://www.shadertoy.com/view/4lsgd1 bool test( out vec3 N, in vec3 D, in vec3 s, in float r ) { float A = dot( D, D ), B = dot( D, s )*(-2.0); float C = dot( s, s ) - r*r, det = B*B - 4.0*A*C; if (det < 0.0 ) return false; float t = (-B+sqrt(det)) / (2.0*A); N = normalize( D*t - s ); return true; } void mainimage( out vec4 color, in vec2 pos ) { float Y = pos.y / iresolution.y; vec3 N, Sky = vec3( 0.45, 0.75, 1.0 )*Y*0.4; vec3 V = normalize( vec3( (pos.xy - iresolution.xy*0.5) / iresolution.xx, 1.0 )); color = vec4(sky,1.0); if (!test( N, V, vec4(0,0,5), 1.0 )) return; vec3 H = normalize( V - reflect(v,n)), L = normalize( vec3(1.0,1.0,1.0)); float dotnl = max(dot(n,l),0.), dothl = max(dot(h,l),0.), spec = pow(dothl,32.); color = vec4(vec3(1,0.5,0.5)*dotnl*0.9 + vec3(1,1,1)*spec*0.9 + Sky,1.); }

Concurrency College 10 OpenCL (1) 30 OpenCL Kernel Shaders op Shadertoy: korte programma s die uitgevoerd worden voor elke pixel van een bitmap. Regular parallelism / Map Geen synchronisatie tussen threads. Uitvoer is 1 pixel, op een vaste locatie. pos pos pos pos pos pos pos pos K K K K K K K K Executie op GPU hardware: Elke pixel van de bitmap is een thread. Groepering van threads in warps en de verdeling over SMs wordt overgelaten aan WebGL / de driver. Eventuele input data voor een kernel wordt aangeboden in de vorm van textures. color color color color color color color color

Concurrency College 10 OpenCL (1) 31 OpenCL Kernel Kernels in OpenCL: korte programma s die uitgevoerd worden voor elke taak in een lijst. Regular parallelism / Map Synchronisatie tussen threads is mogelijk. In- en uitvoer kan complex zijn. in in in in in in in in K K K K K K K K Executie op GPU hardware: Elke taak in de lijst is een thread. Groepering van threads in warps en de verdeling over SMs kan expliciet gespecificeerd worden. Input- en output data in de vorm van textures en/of generieke buffers. Expliciete controle over de memory hierarchy. out out out out out out out out

Concurrency College 10 OpenCL (1) 32 OpenCL OpenCL Specificatie Gebaseerd op C99 Extensies: address space qualifiers work-items workgroups vector types synchronizatie Ingebouwde functies: image manipulation work item manipulation math functies Beperkingen: geen functiepointers geen recursie kernel void SAXPY( global float* x, global float* y, float a, write_only image2d_t image ) { int i = get_global_id( 0 ); y[i] += a * cos( x[i] ); y[i] += a * native_cos( x[i] ); float3 tmp = (float3)(a, a, a ); int2 pos = (int2)(i,0); write_imagef( image, pos, tmp ); tmp = native_cos( tmp ); y[i] += tmp.x; y[i] += tmp.y; y[i] += tmp.z; }

Agenda: Introductie OpenCL OpenCL / C# Workgroups Tot Slot

Concurrency College 10 OpenCL (1) 34 OpenCL / C# OpenTK / Cloo OpenCL kan in C# gebruikt worden via de Cloo library: using Cloo; Om een OpenCL kernel te kunnen gebruiken hebben we nodig: een compute platform een OpenCL context een OpenCL command queue een OpenCL program de kernel

Concurrency College 10 OpenCL (1) 35 OpenCL / C# Devices & Vendors: Compute Platform Het Compute Platform is de interface naar de vendor-specific implementatie van OpenCL. In een systeem met een NVidia GPU zijn in principe twee OpenCL platforms aanwezig: 1. De NVidia OpenCL implementatie; 2. De Intel OpenCL implementatie (voor de CPU). Platform ComputePlatform platform = ComputePlatform.Platforms[0]; Console.Write( platform.name ); // NVIDIA CUDA Console.Write( platform.profile ); // FULL PROFILE

Concurrency College 10 OpenCL (1) 36 OpenCL / C# OpenCL Context In de context wordt de state van de OpenCL API bijgehouden. ComputeContext context = new ComputeContext( ComputeDeviceTypes.Gpu, new ComputeContextPropertyList( platform ), null, IntPtr.Zero ); Platform Context

Concurrency College 10 OpenCL (1) 37 OpenCL / C# Program Een OpenCL program is een collectie kernels. Ook wanneer we maar één kernel hebben wordt deze ondergebracht in een program. var streamreader = new StreamReader( "../../program.cl" ); string clsource = streamreader.readtoend(); streamreader.close(); // create program with opencl source ComputeProgram program = new ComputeProgram( context, clsource ); Compileren van OpenCL code: program.build( null, null, null, IntPtr.Zero ); Platform Context Program

Concurrency College 10 OpenCL (1) 38 OpenCL / C# Kernel We kunnen nu de kernel opvragen: ComputeKernel kernel = program.createkernel( "device_function" ); Platform Context Program Kernel

Concurrency College 10 OpenCL (1) 39 OpenCL / C# Kernel Arguments Stel dat we de volgende kernel willen uitvoeren: kernel void device_function( global float* x, float a ) { int i = get_global_id( 0 ); x[i] *= a; } Deze kernel heeft twee arguments. We geven de data door vanuit C# met: kernel.setmemoryargument( 0, buffer ); kernel.setvalueargument( 1, 3.14159265359f ); Platform Context Program Kernel Arguments

Concurrency College 10 OpenCL (1) 40 OpenCL / C# Buffers In het voorbeeld is een van de argumenten een array van floats. kernel void device_function( global float* x, float a ) { int i = get_global_id( 0 ); x[i] *= a; } Platform Context Program Kernel Arguments Buffers In C#: float [] data = new float[65536]; We maken hier een buffer van waarmee OpenCL kan werken: var flags = ComputeMemoryFlags.ReadWrite ComputeMemoryFlags.UseHostPointer; buffer = new ComputeBuffer<float>( context, flags, data );

Concurrency College 10 OpenCL (1) 41 OpenCL / C# Queue Alles staat nu klaar om uitgevoerd te worden. Kernel execution gaat via een job queue: ComputeCommandQueue queue = new ComputeCommandQueue( context, context.devices[0], 0 ); queue.execute( kernel, null, new long [] { 512 * 512 }, null, null ); queue.finish(); Als laatste stap lezen we de GPU buffer terug naar de C# array. queue.readfrombuffer( buffer, ref data, true, null ); Platform Context Program Kernel Arguments Buffers Queue

Concurrency College 10 OpenCL (1) 42 OpenCL / C# Recap Voor het uitvoeren van een kernel hebben we nodig: een OpenCL platform: platform = ComputePlatform.Platforms[0]; een OpenCL context: context = new ComputeContext( ); een program: program = new ComputeProgram( context, clsource ); de kernel: kernel = program.createkernel( "device_function" ); een job queue: queue = new ComputeCommandQueue( ); We zetten (eenmalig / voor updates) de arguments van de kernel met: SetMemoryArgument / SetValueArgument De kernel wordt uitgevoerd door een job aan de queue toe te voegen: queue.execute( kernel, null, new long [] { N }, null, null ); Platform Context Program Kernel Arguments Buffers Queue

Concurrency College 10 OpenCL (1) 43 OpenCL / C# Voorbeeld Het berekenen van de Mandelbrot set: M = cεc lim n Z n, Z 0 = c, Z n+1 = Z n 2 + c De verzameling M van alle complexe getallen waarvoor geldt dat de recursieve functie Z n voor c niet naar oneindig gaat. In pseudocode: Z re = c real, Z imaginary = c imaginary isinside = true for( n = 0; n < iterations; n++ ) { if (Z 2 real + Z 2 imaginary > 4) { isinside = false; break; } } Z imaginary = 2 Z real Z imaginary + c imaginary Z real = Z 2 real Z 2 imaginary + c real

Concurrency College 10 OpenCL (1) 44 OpenCL / C# Mandelbrot kernel void device_function( global int* a, float t ) { // adapted from inigo quilez - iq/2013 int id = get_global_id( 0 ); if (id >= (512 * 512)) return; float2 fragcoord = (float2)( (id & 511), (float)(id >> 9) ), resolution = (float2)( 512, 512 ); float3 col = (float3)( 0.f, 0.f, 0.f ); for( int m = 0; m < 2; m++ ) for( int n = 0; n < 2; n++ ) { float2 p = -resolution + 2.f * (fragcoord + (float2)(.5f * (float)m,.5f * (float)n )); float w = (float)( 2 * m + n ), l = 0.0f; float time = t +.5f * (1.f / 24.f) * w / 4.f; float zoo =.32f +.2f * cos(.07f * time ); float coa = cos(.15f * (1.f - zoo) * time ); float sia = sin(.15f * (1.f - zoo) * time ); zoo = pow( zoo, 8.f ); float2 xy = (float2)( p.x * coa - p.y * sia, p.x * sia + p.y * coa ); float2 c = (float2)( -.745f,.186f ) + xy * zoo, z = (float2)( 0.f, 0.f ); for( int i = 0; i < 256; i++ ) { z = (float2)( z.x * z.x - z.y * z.y, 2.f * z.x * z.y ) + c; if (dot( z, z ) > 65536.f) break; else l += 1.f; } float sl = l - log2( log2( dot( z, z ) ) ) + 4.f; float al = smoothstep( -.1f, 0.f, 1.f ); l = mix( l, sl, al ); col +=.5f +.5f * cos( 3.f + l * 0.15f + (float3)(.0f,.6f, 1.f ) ); } int r = (int)min( 255.0f, 64.0f * col.x ); int g = (int)min( 255.0f, 64.0f * col.y ); int b = (int)min( 255.0f, 64.0f * col.z ); a[id] = (r << 16) + (g << 8) + b; }

Concurrency College 10 OpenCL (1) 45 OpenCL / C#

Concurrency College 10 OpenCL (1) 46 OpenCL / C#

Agenda: Introductie OpenCL OpenCL / C# Workgroups Tot Slot

Concurrency College 10 OpenCL (1) 48 Workgroups Verdeling van Threads over de SMs In de Mandelbrot renderer hebben we: 512 * 512 = 262.144 threads. De Titan X kan maximaal 49.152 threads tegelijk uitvoeren. De output wordt dus door minstens 5 batches van 49.152 pixels en 1 batch van 16384 pixels verwerkt. Bij deze batch-grootte zijn er per SM 49.152/24 = 2048 threads actief, in 64 warps. Workgroup.

Concurrency College 10 OpenCL (1) 49 Workgroups Verdeling van Threads over de SMs per SM zijn 2048 threads actief, in 64 warps. In het Mandelbrot voorbeeld: 2048 threads voor 2048 pixels, bij een resolutie van 512x512: de pixels van de eerste 4 regels. for( int i = 0; i < 256; i++ ) { z = (float2)(z.x*z.x-z.y*z.y, 2.f*z.x*z.y) + c; if (dot( z, z ) > 65536.f) break; else l += 1.f; } Wat gebeurd er als 1 thread een break doet, en de andere threads door willen gaan?

Concurrency College 10 OpenCL (1) 50 Workgroups Occupancy z=5; if (cond1) 1111 Wat gebeurd er als 1 thread een break doet, en de andere threads door willen gaan? De threads in een warp worden in lockstep uitgevoerd: iedere thread voert dezelfde instructie uit. Masking wordt gebruikt om streams tijdelijk uit te schakelen. Een break in sommige threads in een warp betekent dat sommige threads inactief worden. Occupancy: aantal actieve threads per SM maximaal aantal threads per SM x = y + z; if (cond2) w = t + u; else w = t u; p = q + r; else x = y z; x++; 1110 1000 0110 1110 0001 1111

Concurrency College 10 OpenCL (1) 51 Workgroups Occupancy Wanneer we de totale taak als een 2D probleem beschouwen verbeterd de occupancy: Tiles hebben een betere program flow coherence dan regels.

Concurrency College 10 OpenCL (1) 53 Workgroups Experiment queue.execute( kernel, null, new long [] { 512 * 512 }, null, null ); wordt: int [] worksize = { 512, 512 }; queue.execute( kernel, null, worksize, null, null ); Voor t = 21.5: fps = 30.0 int [] worksize = { 512, 512 }; int [] localsize = { 32,... }; // 2, 4, 8, 16 queue.execute( kernel, null, worksize, localsize, null ); fps = 60.0

Concurrency College 10 OpenCL (1) 54 Workgroups Workgroup Size Waarom is de workgroup size van belang? Een SM heeft een beperkt aantal registers: 64K voor Kepler en Maxwell. 2048 threads = 32 32-bitregisters per thread. Wanneer de compiler onvoldoende registers beschikbaar heeft wordt local memory gebruikt.

Concurrency College 10 OpenCL (1) 55 Workgroups Workgroup Size Waarom is de workgroup size van belang? Een SM heeft snel local memory dat toegankelijk is voor alle threads op de SM.

Concurrency College 10 OpenCL (1) 56 Workgroups Workgroup Size Waarom is de workgroup size van belang? De threads in een workgroup kunnen barriers gebruiken voor synchronisatie.

Agenda: Introductie OpenCL OpenCL / C# Workgroups Tot Slot

Concurrency College 10 OpenCL (1) 58 Tot Slot GL Interop Data flow in Mandelbrot: screen (template) texture Buffer (host) t ReadFromBuffer Buffer (device, write-only) host Execute device

Concurrency College 10 OpenCL (1) 59 Tot Slot GL Interop OpenCL kan een OpenGL texture gebruiken als input / output. Voordeel: de data is al op de GPU, geen verkeer. Voorwaarden: OpenGL context moet gekoppeld worden aan OpenCL context OpenGL texture moet gelocked worden voor OpenCL

Concurrency College 10 OpenCL (1) 60 Tot Slot GL Interop OpenCL / OpenGL koppelen: [System.Runtime.InteropServices.DllImport("opengl32", SetLastError = true)] static extern IntPtr wglgetcurrentdc(); IntPtr glhandle = (GraphicsContext.CurrentContext as IGraphicsContextInternal).Context.Handle; IntPtr wglhandle = wglgetcurrentdc(); var p1 = new ComputeContextProperty(ComputeContextPropertyName.Platform, platform.handle.value); var p2 = new ComputeContextProperty(ComputeContextPropertyName.CL_GL_CONTEXT_KHR, glhandle); var p3 = new ComputeContextProperty(ComputeContextPropertyName.CL_WGL_HDC_KHR, wglhandle); var cpl = new ComputeContextPropertyList(new ComputeContextProperty[] { p1, p2, p3 }); context = new ComputeContext( ComputeDeviceTypes.Gpu, cpl, null, IntPtr.Zero );

Concurrency College 10 OpenCL (1) 61 Tot Slot GL Interop OpenGL texture voor interop aanmaken: float [] texdata = new float[512 * 512 * 4]; ComputeImage2D texbuffer; int texid = GL.GenTexture(); GL.BindTexture( TextureTarget.Texture2D, texid ); GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)textureminfilter.nearest ); GL.TexParameter( TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)texturemagfilter.nearest ); GL.TexImage2D( TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba32f, 512, 512, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgb, PixelType.Float, texdata ); flags = ComputeMemoryFlags.WriteOnly; texbuffer = ComputeImage2D.CreateFromGLTexture2D( context, flags, (int)texturetarget.texture2d, 0, texid );

Concurrency College 10 OpenCL (1) 62 Tot Slot GL Interop OpenGL texture locken / unlocken: List<ComputeMemory> c = new List<ComputeMemory>() { texbuffer }; queue.acquireglobjects( c, null ); queue.execute( kernel, null, worksize, localsize, null ); queue.finish(); queue.releaseglobjects( c, null );

Concurrency College 10 OpenCL (1) 63 Tot Slot GL Interop Render-to-texture is de meest gebruikte toepassing voor GL interop. Andere toepassingen: Mesh simplification Procedural landscapes / meshes Particle systems

Agenda: Introductie OpenCL OpenCL / C# Workgroups Tot Slot

Concurrency College 10 OpenCL (1) 65 Tot Slot Literatuur NVIDIA s Fermi: The First Complete GPU Computing Architecture http://www.nvidia.com/content/pdf/fermi_white_papers/ p.glaskowsky_nvidia's_fermi-the_first_complete_gpu_architecture.pdf Boek: 2.4.3, 2.4.4

Concurrency Gerard Tel / Jacco Bikker - november 2017 februari 2018 EINDE van OpenCL (1) volgende college: OpenCL (2)