Skip to content

Commit 636ae6a

Browse files
committed
add mandelbrot 5.cs
1 parent ad18b20 commit 636ae6a

File tree

1 file changed

+105
-0
lines changed
  • bench/algorithm/mandelbrot

1 file changed

+105
-0
lines changed

bench/algorithm/mandelbrot/5.cs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using System.Runtime.CompilerServices;
2+
using System.Runtime.Intrinsics;
3+
using System.Runtime.Intrinsics.X86;
4+
using System.Security.Cryptography;
5+
6+
namespace mandelbrot;
7+
8+
public static class MandelBrot
9+
{
10+
public static void Main(string[] args)
11+
{
12+
int size = args.Length == 0 ? 200 : int.Parse(args[0]);
13+
size = (size + 7) / 8 * 8;
14+
int rowBytes = size / 8;
15+
double inv = 2.0 / size;
16+
17+
Console.WriteLine($"P4\n{size} {size}");
18+
19+
20+
byte[] data = new byte[size * rowBytes];
21+
22+
// Constants
23+
Vector256<double> idx4 = Vector256.Create(0.0, 1.0, 2.0, 3.0);
24+
Vector256<double> four = Vector256.Create(4.0);
25+
Vector256<double> invV = Vector256.Create(inv);
26+
Vector256<double> neg1_5 = Vector256.Create(-1.5);
27+
28+
Parallel.For(0, size, y =>
29+
{
30+
double ciScalar = y * inv - 1.0;
31+
Vector256<double> ci = Vector256.Create(ciScalar);
32+
33+
for (int xb = 0; xb < rowBytes; xb++)
34+
{
35+
double baseX = xb * 8.0;
36+
37+
38+
Vector256<double> cr0 = Vector256.Add(
39+
Vector256.Multiply(
40+
Vector256.Add(idx4, Vector256.Create(baseX)), invV),
41+
neg1_5);
42+
Vector256<double> cr1 = Vector256.Add(
43+
Vector256.Multiply(
44+
Vector256.Add(idx4, Vector256.Create(baseX + 4.0)), invV),
45+
neg1_5);
46+
47+
byte hi = MBrot4Block5Mask(cr0, ci, four, hiNibble: true);
48+
byte lo = MBrot4Block5Mask(cr1, ci, four, hiNibble: false);
49+
data[y * rowBytes + xb] = (byte)(hi | lo);
50+
}
51+
});
52+
byte[] hash = MD5.HashData(data.AsSpan());
53+
Console.WriteLine(Convert.ToHexString(hash.AsSpan()).ToLowerInvariant());
54+
}
55+
56+
57+
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
58+
private static byte MBrot4Block5Mask( Vector256<double> cr, Vector256<double> ci, Vector256<double> four, bool hiNibble)
59+
{
60+
Vector256<double> zr = Vector256<double>.Zero;
61+
Vector256<double> zi = Vector256<double>.Zero;
62+
Vector256<double> tr = Vector256<double>.Zero;
63+
Vector256<double> ti = Vector256<double>.Zero;
64+
Vector256<double> inside = Vector256<long>.Zero.AsDouble();
65+
66+
for (int outer = 0; outer < 10; outer++)
67+
{
68+
for (int j = 0; j < 5; j++)
69+
{
70+
// zi = (zr + zr) * zi + ci;
71+
Vector256<double> twoZr = Vector256.Add(zr, zr);
72+
zi = Vector256.Add(Vector256.Multiply(twoZr, zi), ci);
73+
74+
// zr = tr - ti + cr; (tr, ti from previous sub-iteration)
75+
zr = Vector256.Add(Vector256.Subtract(tr, ti), cr);
76+
77+
// tr = zr*zr; ti = zi*zi;
78+
tr = Vector256.Multiply(zr, zr);
79+
ti = Vector256.Multiply(zi, zi);
80+
}
81+
82+
Vector256<double> abs2 = Vector256.Add(tr, ti);
83+
inside = Vector256.LessThanOrEqual(abs2, four).AsDouble();
84+
}
85+
86+
int m = Avx.MoveMask(inside);
87+
88+
if (hiNibble)
89+
{
90+
return (byte)(
91+
((m & 1) << 7) |
92+
((m & 2) << 5) |
93+
((m & 4) << 3) |
94+
((m & 8) << 1)
95+
);
96+
}
97+
98+
return (byte)(
99+
((m & 1) << 3) |
100+
((m & 2) << 1) |
101+
((m & 4) >> 1) |
102+
((m & 8) >> 3)
103+
);
104+
}
105+
}

0 commit comments

Comments
 (0)