source code
// The Computer Language Benchmarks Game
// https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
//
// direct transliteration of Greg Buchholz's C program
// contributed by Isaac Gouy, fix by David Turnbull
// dispatching to multiple cores, use SIMD operationn, early break
// depending on previous depth by Patrick Stein,
// direct transliteration of Swift #7 program by Arseniy Zlobintsev
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
const int iterations = 50;
const double depth = 4.0;
var width = int.Parse(args[0]);
var height = width;
var startPoint = (x: -1.5, i: -1.0);
var endPoint = (x: 0.5, i: 1.0);
var lineCount = height;
var lineSize = (width + 7) / 8;
var pixelHeight = Math.Abs(endPoint.x - startPoint.x) / height;
var pixelWidth = Math.Abs(endPoint.i - startPoint.i) / width;
var pixelWidth8 = pixelWidth * 8.0;
var outputSize = lineCount * lineSize;
var pixelBuffer = new byte[outputSize];
var Ci0 = startPoint.i;
var Cr0 = (Vector512.Create((double)0, 1, 2, 3, 4, 5, 6, 7)
* pixelWidth)
+ Vector512.Create(startPoint.x);
var Cr0Array = new Vector512<double>[lineSize];
Parallel.For(0, lineSize, x => {
Cr0Array[x] = Cr0 + Vector512.Create(x * pixelWidth8);
});
Parallel.For(0, lineCount, y => {
var slice = pixelBuffer.AsSpan(y * lineSize, lineSize);
var Ci = Ci0 + (y * pixelHeight);
var pixel = (byte)0;
for (var x = 0; x < slice.Length; x++) {
Mandelbrot(Cr0Array[x], Ci, ref pixel);
slice[x] = pixel;
}
});
Console.WriteLine($"P4\n{width} {height}");
Console.OpenStandardOutput().Write(pixelBuffer);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static void Mandelbrot(Vector512<double> Cr, double Ci, ref byte pixel) {
var Zr = Vector512<double>.Zero;
var Zi = Vector512<double>.Zero;
var Tr = Vector512<double>.Zero;
var Ti = Vector512<double>.Zero;
var CiV = Vector512.Create(Ci);
var thresholds = Vector512.Create(depth);
var ramp = Vector512.Create(128, 64, 32, 16, 8, 4, 2, 1);
if (pixel is 0) {
for (var i = 0; i < iterations / 5; i++) {
for (var j = 0; j < 5; j++) {
Zi = 2.0 * Zr * Zi + CiV;
Zr = Tr - Ti + Cr;
Tr = Zr * Zr;
Ti = Zi * Zi;
}
var result = Vector512.LessThanAny(Tr + Ti, thresholds);
if (result is false) return;
}
}
else {
for (var i = 0; i < iterations; i++) {
Zi = 2.0 * Zr * Zi + CiV;
Zr = Tr - Ti + Cr;
Tr = Zr * Zr;
Ti = Zi * Zi;
}
}
var cmpresult = Vector512.LessThan(Tr + Ti, thresholds);
var summask = ramp & cmpresult.AsInt64();
pixel = (byte)Vector512.Sum(summask);
}
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
.NET SDK 9.0.100
Host Version: 9.0.0
Commit: 9d5a6a9aa4
<OutputType>Exe
<TargetFramework>net9.0
<ImplicitUsings>enable
<Nullable>enable
<AllowUnsafeBlocks>true
<ServerGarbageCollection>true
<ConcurrentGarbageCollection>true
<PublishAot>true
<OptimizationPreference>Speed
<IlcInstructionSet>native
Thu, 14 Nov 2024 00:42:39 GMT
MAKE:
cp mandelbrot.csharpaot-7.csharpaot Program.cs
cp Include/csharpaot/program.csproj .
mkdir obj
cp Include/csharpaot/project.assets.json ./obj
/opt/src/dotnet-sdk-9.0.100/dotnet publish
Determining projects to restore...
Restored /home/dunham/all-benchmarksgame/benchmarksgame_i53330/mandelbrot/tmp/program.csproj (in 1.01 sec).
program -> /home/dunham/all-benchmarksgame/benchmarksgame_i53330/mandelbrot/tmp/bin/Release/net9.0/linux-x64/program.dll
Generating native code
program -> /home/dunham/all-benchmarksgame/benchmarksgame_i53330/mandelbrot/tmp/bin/Release/net9.0/linux-x64/publish/
24.71s to complete and log all make actions
COMMAND LINE:
./bin/Release/net9.0/linux-x64/native/program 16000
(BINARY) PROGRAM OUTPUT NOT SHOWN