The Computer Language
Benchmarks Game

mandelbrot F# .NET Core #3 program

source code

(* The Computer Language Benchmarks Game
   http://benchmarksgame.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
*)

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(&current_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(&current_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
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
F# 4.1.0
dotnet 1.0.1 005db40cd1
"System.GC.Server": true


Sun, 16 Apr 2017 19:06:22 GMT

MAKE:
cp mandelbrot.fsharpcore-3.fsharpcore Program.fs
cp Include/fsharpcore/tmp.fsproj .
cp Include/fsharpcore/runtimeconfig.template.json .
mkdir obj
cp Include/fsharpcore/project.assets.json ./obj
cp Include/fsharpcore/tmp.fsproj.nuget.g.props ./obj
cp Include/fsharpcore/tmp.fsproj.nuget.g.targets ./obj
/usr/bin/dotnet build -c Release
Microsoft (R) Build Engine version 15.1.548.43366
Copyright (C) Microsoft Corporation. All rights reserved.

  tmp -> /home/dunham/benchmarksgame_quadcore/mandelbrot/tmp/bin/Release/netcoreapp1.1/tmp.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:10.83
11.29s to complete and log all make actions

COMMAND LINE:
/usr/bin/dotnet ./bin/Release/netcoreapp1.1/tmp.dll 16000

(BINARY) PROGRAM OUTPUT NOT SHOWN