From b4a145e60f4bbc90dc780239cc49c024b9f52ca8 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 28 Jun 2011 17:58:44 -0700 Subject: [PATCH] Added a nanosecond timer to time.rs, support for some floating point casts, and a commandline-driven mode for pfib.rs --- src/comp/middle/trans.rs | 17 +++++++- src/lib/time.rs | 13 +++++- src/rt/rust_builtin.cpp | 6 +++ src/rt/rustrt.def.in | 1 + src/rt/sync/timer.cpp | 15 ++++--- src/rt/sync/timer.h | 3 +- src/test/bench/shootout/pfib.rs | 73 ++++++++++++++++++++++----------- 7 files changed, 95 insertions(+), 33 deletions(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index c14938a5b61..01ae30bf4e1 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5113,7 +5113,22 @@ fn trans_cast(&@block_ctxt cx, &@ast::expr e, ast::node_id id) -> result { int_cast(e_res.bcx, lldsttype, llsrctype, e_res.val, ty::type_is_signed(cx.fcx.lcx.ccx.tcx, t))); } - } else { cx.fcx.lcx.ccx.sess.unimpl("fp cast"); } + } + else { + if (ty::type_is_integral(cx.fcx.lcx.ccx.tcx, + ty::expr_ty(cx.fcx.lcx.ccx.tcx, e))) { + if (ty::type_is_signed(cx.fcx.lcx.ccx.tcx, + ty::expr_ty(cx.fcx.lcx.ccx.tcx, e))) { + e_res = rslt(e_res.bcx, + e_res.bcx.build.SIToFP(e_res.val, lldsttype)); + } + else { + e_res = rslt(e_res.bcx, + e_res.bcx.build.UIToFP(e_res.val, lldsttype)); + } + } + else { cx.fcx.lcx.ccx.sess.unimpl("fp cast"); } + } ret e_res; } diff --git a/src/lib/time.rs b/src/lib/time.rs index 65d02616294..d2c61b74e98 100644 --- a/src/lib/time.rs +++ b/src/lib/time.rs @@ -2,6 +2,7 @@ native "rust" mod rustrt { fn get_time(&mutable u32 sec, &mutable u32 usec); + fn nano_time(&mutable u64 ns); } type timeval = rec(u32 sec, u32 usec); @@ -11,4 +12,14 @@ fn get_time() -> timeval { auto usec = 0u32; rustrt::get_time(sec, usec); ret rec(sec=sec, usec=usec); -} \ No newline at end of file +} + +fn precise_time_ns() -> u64 { + auto ns = 0u64; + rustrt::nano_time(ns); + ret ns; +} + +fn precise_time_s() -> float { + ret (precise_time_ns() as float) / 1000000000.; +} diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 5b5844fc135..0ccc83435f7 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -612,6 +612,12 @@ get_time(rust_task *task, uint32_t *sec, uint32_t *usec) { } #endif +extern "C" CDECL void +nano_time(rust_task *task, uint64_t *ns) { + timer t; + *ns = t.nano_time(); +} + /** * Preallocates the exact number of bytes in the given interior vector. */ diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 38c51513190..444faccef26 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -15,6 +15,7 @@ ivec_on_heap ivec_reserve ivec_to_ptr last_os_error +nano_time pin_task unpin_task rand_free diff --git a/src/rt/sync/timer.cpp b/src/rt/sync/timer.cpp index e6fe3688893..3af441c3950 100644 --- a/src/rt/sync/timer.cpp +++ b/src/rt/sync/timer.cpp @@ -9,7 +9,7 @@ timer::timer() { #if __WIN32__ uint64_t ticks_per_second; QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second); - _ticks_per_us = ticks_per_second / 1000000; + _ticks_per_ns = ticks_per_second / 1000; #endif reset(0); } @@ -41,7 +41,7 @@ timer::has_timed_out() { } uint64_t -timer::get_time() { +timer::nano_time() { #ifdef __APPLE__ uint64_t time = mach_absolute_time(); mach_timebase_info_data_t info = {0, 0}; @@ -49,18 +49,23 @@ timer::get_time() { mach_timebase_info(&info); } uint64_t time_nano = time * (info.numer / info.denom); - return time_nano / 1000; + return time_nano; #elif __WIN32__ uint64_t ticks; QueryPerformanceCounter((LARGE_INTEGER *)&ticks); - return ticks / _ticks_per_us; + return ticks / _ticks_per_ns; #else timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - return (ts.tv_sec * 1000000000LL + ts.tv_nsec) / 1000; + return (ts.tv_sec * 1000000000LL + ts.tv_nsec); #endif } +uint64_t +timer::get_time() { + return nano_time() / 1000; +} + timer::~timer() { // Nop. } diff --git a/src/rt/sync/timer.h b/src/rt/sync/timer.h index aae098a1119..6d833396cf9 100644 --- a/src/rt/sync/timer.h +++ b/src/rt/sync/timer.h @@ -11,7 +11,7 @@ private: uint64_t _timeout; uint64_t get_time(); #if __WIN32__ - uint64_t _ticks_per_us; + uint64_t _ticks_per_ns; #endif public: timer(); @@ -20,6 +20,7 @@ public: double get_elapsed_time_in_ms(); int64_t get_timeout(); bool has_timed_out(); + uint64_t nano_time(); virtual ~timer(); }; diff --git a/src/test/bench/shootout/pfib.rs b/src/test/bench/shootout/pfib.rs index f7fda8b8110..cbe0813efc4 100644 --- a/src/test/bench/shootout/pfib.rs +++ b/src/test/bench/shootout/pfib.rs @@ -4,38 +4,61 @@ A parallel version of fibonacci numbers. */ +use std; + +import std::vec; +import std::uint; +import std::time; +import std::str; + fn recv[T](&port[T] p) -> T { - let T x; - p |> x; - ret x; + let T x; + p |> x; + ret x; } fn fib(int n) -> int { - fn pfib(chan[int] c, int n) { - if (n == 0) { - c <| 0; + fn pfib(chan[int] c, int n) { + if (n == 0) { + c <| 0; + } + else if (n <= 2) { + c <| 1; + } + else { + let port[int] p = port(); + + auto t1 = spawn pfib(chan(p), n - 1); + auto t2 = spawn pfib(chan(p), n - 2); + + c <| recv(p) + recv(p); + } } - else if (n <= 2) { - c <| 1; + + let port[int] p = port(); + auto t = spawn pfib(chan(p), n); + ret recv(p); +} + +fn main(vec[str] argv) { + if(vec::len(argv) == 1u) { + assert (fib(8) == 21); + assert (fib(15) == 610); + log fib(8); + log fib(15); } else { - let port[int] p = port(); - - auto t1 = spawn pfib(chan(p), n - 1); - auto t2 = spawn pfib(chan(p), n - 2); + // Interactive mode! Wooo!!!! - c <| recv(p) + recv(p); + auto n = uint::parse_buf(str::bytes(argv.(1)), 10u) as int; + auto start = time::precise_time_ns(); + auto fibn = fib(n); + auto stop = time::precise_time_ns(); + + auto elapsed = (stop - start) as int; + auto us_task = elapsed / fibn / 1000; + + log_err #fmt("Determined that fib(%d) = %d in %d ns (%d us / task)", + n, fibn, elapsed, us_task); } - } - - let port[int] p = port(); - auto t = spawn pfib(chan(p), n); - ret recv(p); -} - -fn main() { - assert (fib(8) == 21); - assert (fib(15) == 610); - log fib(8); - log fib(15); }