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:
parent
441c7e0610
commit
b4a145e60f
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.;
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -15,6 +15,7 @@ ivec_on_heap
|
||||
ivec_reserve
|
||||
ivec_to_ptr
|
||||
last_os_error
|
||||
nano_time
|
||||
pin_task
|
||||
unpin_task
|
||||
rand_free
|
||||
|
@ -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.
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user