File: fibrepeat.sml

package info (click to toggle)
smlsharp 4.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 123,732 kB
  • sloc: ansic: 16,725; sh: 4,347; makefile: 2,191; java: 742; haskell: 493; ruby: 305; cpp: 284; pascal: 256; ml: 255; lisp: 141; asm: 97; sql: 74
file content (72 lines) | stat: -rw-r--r-- 1,942 bytes parent folder | download | duplicates (2)
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
structure Pthread =
struct
  type pthread_t = unit ptr  (* ToDo: system dependent *)
  val pthread_create =
      _import "pthread_create"
      : __attribute__((suspend))
        (pthread_t ref, unit ptr, unit ptr -> unit ptr, unit ptr) -> int
  val pthread_join =
      _import "pthread_join"
      : __attribute__((suspend))
        (pthread_t, unit ptr ref) -> int
  fun spawn f =
      let
        val t = ref _NULL
        val r = ref 0
        val e = pthread_create (t, _NULL, fn _ => (r := f (); _NULL), _NULL)
      in
        if e = 0 then (!t, r) else raise Fail "spawn"
      end
  fun join (t, r) =
      (pthread_join (t, ref _NULL); !r)
end

val TIMES = 3 * 5 * 7 * 8  (* dividable by 1-8 *)

structure FibRepeat =
struct

  fun fib 0 = 1
    | fib 1 = 1
    | fib n = fib (n - 1) + fib (n - 2)

  fun repeat 0 m = 0
    | repeat n m = fib m + repeat (n - 1) m

  fun task n m = fn () => repeat n m

  fun start nthreads times n =
      let
        val d = Int.quot (times, nthreads)
        val m = Int.rem (times, nthreads)
        val cnts = List.tabulate (nthreads, fn i => if i < m then d + 1 else d)
        val threads = map (fn i => Pthread.spawn (task i n)) (tl cnts)
        val r = task (hd cnts) n ()
      in
        foldl (fn (t,z) => Pthread.join t + z) r threads
      end

end

structure Main =
struct
  fun run () =
      let
        val nthreads =
            case Option.map Int.fromString (OS.Process.getEnv "NTHREADS") of
              SOME (SOME n) => n
            | _ => 1
        val fibn =
            case Option.map (StringCvt.scanString (Word.scan StringCvt.DEC))
                            (OS.Process.getEnv "FIBN") of
              SOME (SOME n) => Word.toInt n
            | _ => 30
      in
        FibRepeat.start nthreads TIMES fibn
      end
(*
  fun doit () = (run (); ())
*)
  fun testit out = TextIO.output (out, Int.toString (run ()) ^ "\n")
  fun doit () = testit TextIO.stdOut
end