I think that was the case for 1.9 definitely. As of 1.10 Darwin is the
fastest by far. Even on bare metal my linux tests are taking 100ns to
compute time.Now vs 11ns on an average OS/X laptop.

As I mentioned the main constraint at this point is the overhead to run a
time.Sleep() which is steep. Reading code it looks like it parks the
goroutine for X time and I'm doubting scheduling latency is down in the low
nanoseconds right now. So either simulating using something known with low
cost (like back/back time.Now() calls) or invoking inlined assembly it
looks like.

James


On Sat, Mar 3, 2018 at 5:23 AM, Donovan Hide <donovanh...@gmail.com> wrote:

> Looks like you may have hit this:
>
> https://github.com/golang/go/issues/22601
>
> On 3 March 2018 at 09:30, James Chacon <chacon.ja...@gmail.com> wrote:
>
>>
>>
>> On Thu, Mar 1, 2018 at 11:59 PM, James Chacon <chacon.ja...@gmail.com>
>> wrote:
>>
>>>
>>>
>>> On Thu, Mar 1, 2018 at 11:07 PM, James Chacon <chacon.ja...@gmail.com>
>>> wrote:
>>>
>>>>
>>>>
>>>> On Thu, Mar 1, 2018 at 10:13 AM, Ian Lance Taylor <i...@golang.org>
>>>> wrote:
>>>>
>>>>> On Thu, Mar 1, 2018 at 8:56 AM, James Chacon <chacon.ja...@gmail.com>
>>>>> wrote:
>>>>> >
>>>>> > I know the time package includes support for using the cycle timer
>>>>> on the
>>>>> > machine (if available) to get high precision monotonic time
>>>>> measurements.
>>>>> >
>>>>> > But...calling time.Now() appears to have a lot of overhead.
>>>>> Measuring the
>>>>> > delay between 2 consecutive calls gives me anywhere from 150ns to
>>>>> 900+ns
>>>>> > depending on arch (linux and OS/X for these 2 examples).
>>>>> >
>>>>> > My problem is I'm writing an emulator for an 8 bit cpu and on
>>>>> certain types
>>>>> > of emulation I want it to run at original clock speeds (so 550ns
>>>>> clock
>>>>> > cycles or so in this case). Just measuring time.Now() at the start
>>>>> of a
>>>>> > cycle and then subtracting time.Now() at the end to sleep for
>>>>> remaining
>>>>> > won't work if the overhead of the calls exceeds my cycle time like
>>>>> it's
>>>>> > doing on OS/X. I'm assuming negligible enough overhead for
>>>>> time.Sleep().
>>>>> >
>>>>> > I know for benchmarking we deal with this by aggregating a lot of
>>>>> samples
>>>>> > and then dividing out. Is there a way to get the timer data much
>>>>> quicker?
>>>>> > I'm assuming on OS/X it's ending up doing the syscall for
>>>>> gettimeofday (I
>>>>> > recall an open bug somewhere) which is where the large jump comes
>>>>> from.
>>>>> >
>>>>> > Or should I just measure my average latency when initializing my
>>>>> emulator
>>>>> > and use that as a baseline for determining how much to sleep? i.e.
>>>>> > effectively a mini benchmark on startup to determine local machine
>>>>> average
>>>>> > run time and assume some slop?
>>>>>
>>>>> I don't think there is any way we could make time.Now run noticeably
>>>>> faster on Darwin.  It's not doing a system call of any sort.
>>>>>
>>>>>
>>>> I'm reading time·now in the 1.9.2 sources and it clearly has a fallback
>>>> path to invoking the gettimeofday call.
>>>>
>>>> I hadn't looked at 1.10 yet so I'll update and check my results there.
>>>>
>>>>
>>>>> Your best bet, if you can assume you are running on amd64, is a tiny
>>>>> bit of assembly code to execute the rdtsc instruction.  rdtsc has its
>>>>> problems, but it will give you fairly accurate cycle time when it's
>>>>> not way way off.
>>>>>
>>>>>
>>>> I may go with that.
>>>>
>>>>
>>> Wow...Ok, updating to 1.10 made a *huge* difference here. On 1.9.2
>>> Darwin was showing an average of 811ns for back to back time.Now() calls.
>>> On 1.10 it's 11-13ns :) I haven't tested amd64 linux yet but I'll assume
>>> it's similar.
>>>
>>> At that amount I can just go back to calling time.Now() at the start/end
>>> and sleeping for the difference modula some slop.
>>>
>>>
>> Looks like I may have to go with assembly for the sleep part or just call
>> time.Now() N times in a row (since it's got decent granularity now in
>> 1.10).
>>
>> The overhead for time.Sleep (using select of some form on darwin/linux it
>> appears) doesn't get anywhere near good enough granularity. 100-200
>> microseconds extra lag on a GCE instance (yes I know a virtual machine will
>> be slower but...) and also on a native darwin setup that only shows the
>> 11-13ns hit for time.Now().
>>
>> Might be worth a note in the time.Sleep() docs indicating very low
>> durations are unlikely to work well.
>>
>> James
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to