[MLton] Re: [MLton-user] FFI and pointer relocation
Wesley W. Terpstra
wesley at terpstra.ca
Wed Nov 28 03:25:10 PST 2007
On Nov 27, 2007, at 5:15 AM, Matthew Fluet wrote:
> I suppose one could use MLton.Pointer functions to fetch the tv_sec
> and tv_usec fields of the statically allocated struct timeval,
> though the overhead of making a C call is really the fact that one
> needs to move ML pointers to the stack, not leaving them in
> registers. So, while there is some overhead of the subsequent C
> calls, it probably isn't that much over the initial call, especially
> since the gettimeofday is a system call. Also, you need to be robust
> against changes to the suseconds_t representation on different
> platforms, and the offset in the timeval struct. So, I'm not sure
> the added complexity is worth it.
The cost of running gettimeofday() is actually dominated by the IntInf
conversions (not the system call). Once those are eliminated by using
Int64, you're right that the two extra function calls have almost no
cost.
I was mostly proposing this because I think it's actually *simpler*
than the additional function calls: My proposal is that gettimeofday()
call should copy the values from a locally scoped timeval struct into
globally scoped C_Time_t and C_SUSeconds_t values which can be (type-
safely) fetched via _symbol:
C_Time_t Time_sec;
C_SUSeconds_t Time_usec;
int gettimeofday() {
struct timeval timeval;
int res;
res = gettimeofday (&timeval, (struct timezone*)NULL);
Time_sec = timeval.tv_sec;
Time_usec = timeval.tv_usec;
return res;
}
>> On the topic of gettimeofday, isn't Time.time as an IntInf instead
>> of an Int64 a bit costly?
>
> Not necessarily. Small IntInf values (< 31 bits or < 63 bits,
> depending on the platform) are maniputated directly, with just a
> couple of bit shifts and arithmetic ops. It is only if you need
> more bits that you need to use the GMP library code, which is itself
> pretty fast.
Except that all uses of Time.time larger than 1 second will be larger
than 30 bits (signed).
> Also, to preserve nanosecond resolution in time values, you either
> need to use IntInf or two fixed integer values, and the added
> complexity of doing the appropriate sec/nanosec pair arithmetic.
I proposed Int64. That's good until the year 2242 at nanosecond
accuracy.
> Time.time manipulations are rare to begin with, and I've never seen
> them be a dominant factor in a program
In a well written network application, an strace looks like: select()
gettimeofday() maybe read() maybe write() gettimeofday() repeat. I was
pleasantly surprised to see that Time.now () can be called about 1M/s.
However, due to the IntInf arithmetic, it's actually 4* slower than
Int64 gettimeofday() on powerpc/osx and 1.5* on x86/linux. It also
wastes about 140 bytes of heap. It's interesting the osx system calls
are so much faster.
Time.time values are also used for inequality tests in event heaps
(which can be very large in simulators).
More information about the MLton
mailing list