From 0eda244ce2b1709c03a3c320daee71d17f895950 Mon Sep 17 00:00:00 2001 From: profan Date: Fri, 5 Jun 2026 00:09:12 +0100 Subject: [PATCH] add the ability to toggle parallelism --- Program.cs | 40 +++++++++++++++++++++++++++++------ Sharpero.sln.DotSettings.user | 1 + 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/Program.cs b/Program.cs index c1856ae..f4b7b0b 100644 --- a/Program.cs +++ b/Program.cs @@ -13,6 +13,8 @@ using SkiaSharp; Main(); +const string programsProsperoVm = "Programs/prospero.vm"; + // STAThread is required if you deploy using NativeAOT on Windows // See https://github.com/raylib-cs/raylib-cs/issues/301 [STAThread] @@ -30,7 +32,7 @@ void Main() void main() { - float v = texture(texture0, fragTexCoord).r< 0 ? 1.0 : 0.0; + float v = texture(texture0, fragTexCoord).r < 0 ? 1.0 : 0.0; outputColor = vec4(v, v, v, 1.0f) * fragColor; } """; @@ -58,7 +60,11 @@ void Main() currentOutputTexture = Raylib.LoadTextureFromImage(currentOutputImage); } } + + bool shouldUseParallelism = true; + bool shouldUseSimd = true; + bool isEvaluating = false; bool shouldEvaluate = false; bool shouldCancelUpdateTexture = false; bool shouldUpdateTexture = false; @@ -69,17 +75,20 @@ void Main() Raylib.ClearBackground(Color.White); - if (shouldEvaluate) + if (shouldEvaluate & !isEvaluating) { shouldUpdateTexture = true; currentOutputImageData.AsSpan()[..currentOutputImageData.Length].Clear(); + + InterpreterOptions interpreterOptions = (shouldUseParallelism ? InterpreterOptions.Parallelism : default); Task.Run(() => { - Instruction[] instructions = Parsing.Parse("Programs/prospero.vm"); - Interpreter.Evaluate(instructions, imageSize: currentOutputImageSize, currentOutputImageData); + Instruction[] instructions = Parsing.Parse(programsProsperoVm); + Interpreter.Evaluate(instructions, imageSize: currentOutputImageSize, interpreterOptions, currentOutputImageData); Raylib.UpdateTexture(currentOutputTexture, currentOutputImageData); shouldCancelUpdateTexture = true; + isEvaluating = false; }); shouldEvaluate = false; @@ -100,6 +109,7 @@ void Main() Raylib.EndShaderMode(); Raylib.DrawText("Sharpero (press R to evaluate, O to output to file)", 12, 12, 20, Color.White); + Raylib.DrawText($" - parallelism {(shouldUseParallelism ? "enabled" : "disabled")} (P to toggle)", 12, 32, 20, Color.White); if (Raylib.IsKeyPressed(KeyboardKey.R)) { @@ -114,6 +124,11 @@ void Main() }); } + if (Raylib.IsKeyPressed(KeyboardKey.P)) + { + shouldUseParallelism = !shouldUseParallelism; + } + Raylib.EndDrawing(); } @@ -130,7 +145,7 @@ float[] GenerateOutputImage(int currentImageSize, bool shouldWriteOutputImage = { (float[] result, double timeTakenSecondsEvaluate) = BenchmarkFunction(() => { - Instruction[] instructions = Parsing.Parse("Programs/prospero.vm"); + Instruction[] instructions = Parsing.Parse(programsProsperoVm); return Interpreter.Evaluate(instructions, imageSize: currentImageSize); }); @@ -378,14 +393,25 @@ internal static class Parsing } } +[Flags] +internal enum InterpreterOptions +{ + Parallelism = 0x1 +} + internal static class Interpreter { - public static float[] Evaluate(Instruction[] instructions, int imageSize, float[]? result = null) + public static float[] Evaluate(Instruction[] instructions, int imageSize, InterpreterOptions options = default, float[]? result = null) { result ??= new float[imageSize * imageSize]; + ParallelOptions parallelOptions = new ParallelOptions() + { + MaxDegreeOfParallelism = (options & InterpreterOptions.Parallelism) != 0 ? -1 : 1 + }; + int chunkSize = Vector.Count; - Parallel.For(0, (imageSize * imageSize) / chunkSize, chunkIdx => + Parallel.For(0, (imageSize * imageSize) / chunkSize, parallelOptions, chunkIdx => { Span xs = stackalloc float[chunkSize]; Span ys = stackalloc float[chunkSize]; diff --git a/Sharpero.sln.DotSettings.user b/Sharpero.sln.DotSettings.user index 2a4543d..501169c 100644 --- a/Sharpero.sln.DotSettings.user +++ b/Sharpero.sln.DotSettings.user @@ -2,6 +2,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded