This is a problem (for me), when trying to get timing information in
the inner loop of my application. Having done some profiling, I'm
seeing that these time allocations are responsible for 14% of the
memory allocated in my application (the inner loop runs a lot). I
looked a bit at hacking a native C function into src/pkg/time, but it
required introducing native code to that package which formerly had
none (which I'm assuming would be frowned upon). Any other
suggestions?
graham
It seems to me the long-term solution lies in package syscall, not package os, by invoking a different helper.
However, you've all but described your own short-term solution. For now, call syscall.Gettimeofday yourself.
-rob
Russ
We could change syscall.Gettimeofday to return three values (sec, usec,
err). Actually then the error code would be unnecessary, so it could
just return two values. But we would have to write it in assembler for
most targets.
Ian
Ah. I looked at the wrong place in the package.
This is just a bug in syscall.
Package runtime already does this.
Russ
Thanks.
graham
If he was calling this with his own Timeval that he only allocates
once, doesn't that solve his allocation problem?
That's what I was suggesting, just less clearly.
-rob
> Maybe the "unsafe" package (which is already used by package
> "syscall", using it from "os" shouldn't cause any problems) should
> gain support for allocating memory on the stack. The "os.Time"
> function could use it to get the space for the result of function
> "syscall.Gettimeofday". One option is to introduce a function like
> "unsafe.AddressOf(v ArbitraryType) Pointer", which would simply return
> the memory address of 'v'. The 8g/6g/5g compilers would implement
> AddressOf by emitting a couple of instructions. The main difference
> between "&v" and "AddressOf(v)" is that the latter will not force the
> variable to be heap-allocated:
>
> func Time() (sec int64, nsec int64, err Error) {
> var tv syscall.Timeval
> if e := syscall.Gettimeofday( unsafe.AddressOf(tv) ); iserror(e) {
> return 0, 0, NewSyscallError("gettimeofday", e)
> }
> return int64(tv.Sec), int64(tv.Usec) * 1000, err
> }
Besides all the other consequences of this mixing of allocation models, this sort of optimization is what compilers are for. See the mention of 'escape analysis' earlier in this thread.
-rob
> I think you are wrong about the fact that a compiler can do escape
> analysis in the case of the code we are talking about. If you think
> escape analysis is possible here, then I would like you to describe
> the course of actions that would lead a Go compiler to the conclusion
> that variable "tv" in function "os.Time" does not need to be allocated
> on the heap. I think such a sequence of actions simply does not exist,
> so escape analysis is *impossible* here.
>
> The only way for "tv" not to be heap-allocated is for the programmer
> to explicitly tell the compiler what the function
> "syscall.Gettimeofday" is doing with its arguments. Obviously, the
> explicitness also implies that it is unsafe (i.e: the programmer is
> providing the compiler with a piece of information that the compiler
> has no way of verifying, and so the compiler has to work under the
> assumption (blind belief) that the provided information is correct).
In general we have to annotate every function written in assembler which
takes a pointer argument. There is nothing wrong with that, as
functions written in assembler are unsafe no matter how you look at
them. In this case we would be annotating syscall.Gettimeofday on some
systems and syscall.Syscall on others, whichever is written in assembler
(as far as I can see, no pointer passed to a system call ever escapes).
Once we've done those annotations, though, the compiler can do escape
analysis building on that. (It's important to note that we would
annotate syscall.Syscall where it is defined in the syscall package; we
would not be annotating syscall.Gettimeofday at the point where os.Time
calls it.)
Ian
> Ok. Are you talking about user-visible language specification changes,
> or about compiler-specific annotations?
Compiler-specific annotations.
No Go language specification change, but the assembler and possibly the
C compiler (6c/8c) would need to support some sort of pragma or other
mechanism for adding the annotations.
Ian