Example uses NuGet package ComputeSharp 3.1.0
using System.Diagnostics; using ComputeSharp; namespace GpuTestConsole { public class Program { static void Main(string[] args) { var sw = new Stopwatch(); // Input arrays float[] input1 = { 1, 2, 3, 4 }; float[] input2 = { 5, 6, 7, 8 }; float[] input3 = { 9, 10, 11, 12 }; // Output array float[] output = new float[input1.Length]; var gpu = GraphicsDevice.GetDefault(); Console.WriteLine($"GPU: {gpu.Name}"); Console.WriteLine($"Compute units: {gpu.ComputeUnits}"); // Allocate buffers once using var inputBuffer = gpu.AllocateReadOnlyBuffer<float>(input1.Length); using var outputBuffer = gpu.AllocateReadWriteBuffer<float>(output.Length); // Create the kernel (without running it yet) var kernel = new AddKernel(inputBuffer, inputBuffer, outputBuffer); // First computation inputBuffer.CopyFrom(input1); kernel.InputBuffer2.CopyFrom(input2); // Dynamically set second input buffer sw.Start(); gpu.For(input1.Length, kernel); // Copy result outputBuffer.CopyTo(output); Console.WriteLine($"Result 1: {string.Join(", ", output)} ({sw.ElapsedMilliseconds} ms)"); // Second computation with new inputs inputBuffer.CopyFrom(input3); kernel.InputBuffer2.CopyFrom(input1); sw.Restart(); gpu.For(input1.Length, kernel); outputBuffer.CopyTo(output); Console.WriteLine($"Result 2: {string.Join(", ", output)} ({sw.ElapsedMilliseconds} ms)"); } } [GeneratedComputeShaderDescriptor] [ThreadGroupSize(DefaultThreadGroupSizes.X)] public partial struct AddKernel : IComputeShader { public ReadOnlyBuffer<float> InputBuffer1; public ReadOnlyBuffer<float> InputBuffer2; public ReadWriteBuffer<float> OutputBuffer; public AddKernel(ReadOnlyBuffer<float> input1, ReadOnlyBuffer<float> input2, ReadWriteBuffer<float> output) { InputBuffer1 = input1; InputBuffer2 = input2; OutputBuffer = output; } /* Aandachtspunten bij Execute Thread Safety: De GPU voert de Execute-functie parallel uit voor elk element. Vermijd gedeelde variabelen (globals) en zorg dat elke thread alleen zijn eigen index gebruikt. Thread Index: Gebruik ThreadIds.X voor de 1D-index. Voor 2D- of 3D-berekeningen kun je ook ThreadIds.Y en ThreadIds.Z gebruiken. Controleer altijd of de thread binnen het bereik van de buffer zit om out-of-bounds fouten te voorkomen. Buffer Types: Gebruik ReadOnlyBuffer<T> voor buffers die niet worden gewijzigd. Gebruik ReadWriteBuffer<T> voor buffers die worden gelezen en geschreven. Debugging: Fouten in GPU-shaders kunnen lastig te debuggen zijn. Controleer of alle indexberekeningen correct zijn en zorg dat buffers voldoende groot zijn. Prestatieoptimalisatie: Voorkom onnodige synchronisaties tussen CPU en GPU. Combineer meerdere kleine berekeningen in één kernel om overhead te verminderen. */ public void Execute() { int i = ThreadIds.X; OutputBuffer[i] = InputBuffer1[i] + InputBuffer2[i]; } } }
917800cookie-checkC# Running computations on GPU