forked from nblockchain/fantomless
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmandelbrot3.fs
82 lines (77 loc) · 2.47 KB
/
mandelbrot3.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/// The Computer Language Benchmarks Game
/// http://shootout.alioth.debian.org/
///
/// Adapted by Antti Lankila from the earlier Isaac Gouy's implementation
/// Add multithread & tweaks from C++ by The Anh Tran
/// Translate to F# by Jomo Fisher
module Mandelbrot
open System
open System.Threading
open System.IO
let mutable N = 200
let mutable width_bytes = 0
let mutable data : byte array array = null
let mutable nbyte_each_line : int array = null
let current_line = ref -1
let Calculate() =
let inverse_n = 2.0 / float N
let mutable y = Interlocked.Increment(¤t_line.contents)
while y < N do // fetch a line
let pdata = data.[y]
let mutable byte_count = 0
let mutable bit_num = 0
let mutable byte_acc = 0
let Civ = float y * inverse_n - 1.0
for x in 0..N - 1 do
let Crv = float x * inverse_n - 1.5
let mutable Zrv = Crv
let mutable Ziv = Civ
let mutable Trv = Crv * Crv
let mutable Tiv = Civ * Civ
let mutable i = 49
let mutable more = true
while more do
Ziv <- (Zrv * Ziv) + (Zrv * Ziv) + Civ
Zrv <- Trv - Tiv + Crv
Trv <- Zrv * Zrv
Tiv <- Ziv * Ziv
more <- (Trv + Tiv) <= 4.0
if more then
i <- i - 1
more <- i > 0
byte_acc <- byte_acc <<< 1
byte_acc <- byte_acc ||| (if i = 0 then 1
else 0)
bit_num <- bit_num + 1
if bit_num = 8 then
pdata.[byte_count] <- byte byte_acc
byte_count <- byte_count + 1
bit_num <- 0
byte_acc <- 0
if bit_num <> 0 then // write left over bits
byte_acc <- byte_acc <<< (8 - (N &&& 7))
pdata.[byte_count] <- byte byte_acc
byte_count <- byte_count + 1
nbyte_each_line.[y] <- byte_count
y <- Interlocked.Increment(¤t_line.contents)
[<EntryPoint>]
let main args =
if args.Length > 0 then N <- int args.[0]
Console.Out.WriteLine("P4\n{0} {0}", N)
width_bytes <- N / 8
if width_bytes * 8 < N then width_bytes <- width_bytes + 1
nbyte_each_line <- Array.zeroCreate N
data <- Array.zeroCreate N
for i in 0..N - 1 do
data.[i] <- Array.zeroCreate width_bytes
let threads =
Array.init (Environment.ProcessorCount - 1) (fun i -> new Thread(Calculate))
for thread in threads do
thread.Start()
Calculate()
for thread in threads do
thread.Join()
let s = Console.OpenStandardOutput()
for y in 0..N - 1 do
s.Write(data.[y], 0, nbyte_each_line.[y])
0