performance measurements

Each table row shows performance measurements for this F# Mono program with a particular command-line input value N.

 N  CPU secs Elapsed secs Memory KB Code B ≈ CPU Load
250,000Failed  1505   

Read the ↓ make, command line, and program output logs to see how this program was run.

Read k-nucleotide benchmark to see what this program should do.

 notes

F# Compiler for F# 3.1 (Open Source Edition)

Mono JIT compiler version 4.1.0 (master/435cc01 Wed May 20 22:58:47 PDT 2015)
LLVM: yes(3.6.0svn-mono-master/ce4fcec)
GC: sgen

 k-nucleotide F# Mono #4 program source code

(* The Computer Language Benchmarks Game
   http://benchmarksgame.alioth.debian.org/
 *
 * contributed by Don Syme
 * based on C# contribution by Isaac Gouy, Antti Lankila, A.Nahr, The Anh Tran
 * Uses native pointer access to one big pinned blob, plus simple task runner
 *)

#nowarn "9"

open System
open System.IO
open System.Collections.Generic
open System.Text
open System.Threading
open System.Runtime.InteropServices
open Microsoft.FSharp.NativeInterop

let toBytes (s: string) = s.ToCharArray() |> Array.map byte
let toString (s: byte []) = String(s |> Array.map char)
let prefixes = [| "ggt"; "ggta"; "ggtatt"; "ggtattttaatt"; "ggtattttaatttatagt" |]

let prefixBytes = 
    [| for p in prefixes -> toBytes p |]

let prefixLengths = 
    [| for p in prefixBytes -> p.Length |]

let prefixOffsets = Array.scan (+) 0 prefixLengths
let dnaStart = prefixOffsets.[prefixLengths.Length]

let createDNA() = 
    //let input = File.OpenText("knucleotide-input-2500000.txt")
    let input = new StreamReader(Console.OpenStandardInput())
    
    let text = 
        seq { 
            while true do
                yield input.ReadLine()
        }
        |> Seq.takeWhile (fun x -> x <> null)
        |> Seq.skipWhile (fun x -> not (x.StartsWith(">THREE")))
        |> Seq.skip 1
        |> String.concat ""
    
    // convert the text to a pinned array of bytes
    let bytes = 
        text
        |> toBytes
        |> Array.append (Array.concat prefixBytes)
    
    let h = GCHandle.Alloc(bytes, GCHandleType.Pinned)
    let addr = h.AddrOfPinnedObject() |> NativePtr.ofNativeInt
    addr, bytes.Length

let dna, dnaLength = createDNA()
let inline readDNA i = NativePtr.get dna i

let inline readDNABytes s n = 
    let res = Array.zeroCreate n
    for i in 0..n - 1 do
        res.[i] <- NativePtr.get dna (s + i)
    res

let keyHash (k, n) = 
    let mutable hash = 0
    for i in 0..n - 1 do
        hash <- hash * 31 + int (readDNA (k + i))
    hash

let keyText (k, n) = toString(readDNABytes k n).ToUpper()

type Value = 
    { mutable value: int
      key: int * int }

let generateFrequencies (frameSize) = 
    let freq = Dictionary<int, Value>()
    let mutable v = Unchecked.defaultof<Value>
    for i in dnaStart..dnaLength - frameSize do
        let h = keyHash (i, frameSize)
        if freq.TryGetValue(h, &v) then v.value <- v.value + 1
        else freq.Add(h, { value = 1; key = (i, frameSize) })
    freq

let writeCount (n: int) = 
    let freq = generateFrequencies (prefixLengths.[n])
    let hash = keyHash (prefixOffsets.[n], prefixLengths.[n])
    
    let count = 
        if freq.ContainsKey(hash) then freq.[hash].value
        else 0
    String.Format("{0}\t{1}", count, prefixes.[n].ToUpper())

type Pair = KeyValuePair<int, Value>

let writeFrequencies (nucleotideLength) = 
    let freq = generateFrequencies (nucleotideLength)
    let items = new ResizeArray<Pair>(freq)
    items.Sort(fun (p1: Pair) (p2: Pair) -> 
        let c = p2.Value.value - p1.Value.value
        if c = 0 then keyText(p1.Value.key).CompareTo(keyText(p2.Value.key))
        else c)
    let buf = new StringBuilder()
    let sum = dnaLength - dnaStart - nucleotideLength + 1
    for element in items do
        let percent = double element.Value.value * 100.0 / double sum
        buf.AppendFormat("{0} {1:f3}\n", keyText element.Value.key, percent) |> ignore
    buf.ToString()

let runTasks (tasks: (unit -> 'T) []) = 
    let taskCount = ref tasks.Length
    let results = Array.zeroCreate tasks.Length
    
    let rec worker() = 
        let j = Interlocked.Decrement(&taskCount.contents)
        if j >= 0 then 
            results.[j] <- tasks.[j]()
            worker()
    
    let threads = 
        Array.init Environment.ProcessorCount (fun i -> 
            let t = new Thread(worker)
            t.Start()
            t)
    
    for t in threads do
        t.Join()
    results

let results = 
    runTasks [| yield (fun () -> writeFrequencies 1)
                yield (fun () -> writeFrequencies 2)
                for i in 0..prefixes.Length - 1 do
                    yield (fun () -> writeCount i) |]

//let endTime = System.DateTime.Now.Ticks
for s in results do
    Console.Out.WriteLine(s)

 make, command-line, and program output logs

Wed, 27 May 2015 04:18:34 GMT

MAKE:
mv knucleotide.fsharp-4.fsharp knucleotide.fsharp-4.fs
/usr/local/bin/fsharpc --target:exe --platform:x64 -O  -o knucleotide.fsharp-4.fsharp_run.exe knucleotide.fsharp-4.fs
F# Compiler for F# 3.1 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License

/home/dunham/benchmarksgame_quadcore/knucleotide/tmp/knucleotide.fsharp-4.fs(9,1): warning FS0221: The declarations in this file will be placed in an implicit module 'Knucleotide.fsharp-4' based on the file name 'knucleotide.fsharp-4.fs'. However this is not a valid F# identifier, so the contents will not be accessible from other files. Consider renaming the file or adding a 'module' or 'namespace' declaration at the top of the file.
rm knucleotide.fsharp-4.fs
5.08s to complete and log all make actions

COMMAND LINE:
/usr/local/bin/mono --llvm --gc=sgen knucleotide.fsharp-4.fsharp_run.exe 0 < knucleotide-input250000.txt

PROGRAM FAILED 


PROGRAM OUTPUT:

mono: /usr/local/src/llvm/include/llvm/IR/Instructions.h:999: void llvm::ICmpInst::AssertOK(): Assertion `getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to ICmp instruction are not of the same type!"' failed.
Stacktrace:

  at <unknown> <0xffffffff>
  at <StartupCode$knucleotide-fsharp-4-fsharp_run>.$Knucleotide.fsharp-4.main@ () <0x000cd>
  at (wrapper runtime-invoke) object.runtime_invoke_void (object,intptr,intptr,intptr) <0xffffffff>

Native stacktrace:

	/usr/local/bin/mono() [0x61d0e0]
	/lib/x86_64-linux-gnu/libpthread.so.0(+0x10d10) [0x7f8f5fe53d10]
	/lib/x86_64-linux-gnu/libc.so.6(gsignal+0x37) [0x7f8f5f898267]
	/lib/x86_64-linux-gnu/libc.so.6(abort+0x16a) [0x7f8f5f899eca]
	/lib/x86_64-linux-gnu/libc.so.6(+0x2e03d) [0x7f8f5f89103d]
	/lib/x86_64-linux-gnu/libc.so.6(+0x2e0f2) [0x7f8f5f8910f2]
	/usr/local/bin/mono() [0x7da6c6]
	/usr/local/bin/mono(LLVMBuildICmp+0x47) [0x112b6c7]
	/usr/local/bin/mono() [0x658617]
	/usr/local/bin/mono() [0x6922b9]
	/usr/local/bin/mono() [0x6930b7]
	/usr/local/bin/mono() [0x59ee7c]
	/usr/local/bin/mono() [0x59f4bb]
	/usr/local/bin/mono() [0x61e370]
	[0x40c56166]

Debug info from gdb:


=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

Revised BSD license

  Home   Conclusions   License   Play