Added a nanosecond timer to time.rs, support for some floating point casts, and a commandline-driven mode for pfib.rs

This commit is contained in:
Eric Holk 2011-06-28 17:58:44 -07:00
parent 441c7e0610
commit b4a145e60f
7 changed files with 95 additions and 33 deletions

View file

@ -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;
}

View file

@ -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);
}
}
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.;
}

View file

@ -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.
*/

View file

@ -15,6 +15,7 @@ ivec_on_heap
ivec_reserve
ivec_to_ptr
last_os_error
nano_time
pin_task
unpin_task
rand_free

View file

@ -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.
}

View file

@ -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();
};

View file

@ -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);
}