Irrespective of the language, these sort of delays are always at the mercy 
of the scheduling jitter of the underlying operating system.
The operating system is at liberty to preempt any application at any time, 
and then resume it some arbitrary time later. If you ask the OS to sleep 
for 
1ms, the OS will deschedule the process, and then resume at some point in 
time after 1ms. Exactly how long after depends 
on what else is running on the processor, contention for cores etc. Once 
the process gets to run again, the Go runtime 
does its own scheduling, it may have many more goroutines ready to run than 
it has available OS threads. So the gorountine which 
is waiting on the ticker could wait an arbitrary amount of time beyond the 
minimum 1ms delay.

The demand for all delays to be within 5% of 1ms is hard to achieve in any 
language running on top of a general purpose (non-realtime) OS,  and is 
double hard in Go which adds an additional layer of scheduling.

A better approach would be to start with a 1ms ticker, but then at each 
tick calculate the amount of time which has actually elapsed, and then send 
the required number of requests to catch-up with the required request rate. 
This will mean a slightly uneven and jittery request rate at the 
microscopic level, and the amount of jitter will be affected by how heavily 
loaded the machine is. But the request rate will even out when looking over 
longer time periods. This will be the best you can do in Go, or in 
user-space in any language running on a non-real-time OS. 


On Monday, 31 January 2022 at 13:50:35 UTC ren...@ix.netcom.com wrote:

> Sorry for typos. Early morning on small phone with no coffee and old 
> person eyes. :)
>
> On Jan 31, 2022, at 7:13 AM, Robert Engels <ren...@ix.netcom.com> wrote:
>
> 
>
> If you need a “guarantee” in these efforts it is much more complex. You 
> must likely need a real-time OS and interrupt driven code. A general 
> purpose language, os and hardware probably won’t cut it. 
>
> This of it this way though, if you had 20 cpus to spread the work on, you 
> only need to interrupt every 10 ms - far more achievable. As long as the 
> work is independent. 
>
> On Jan 30, 2022, at 11:10 PM, envee <neeraj....@gmail.com> wrote:
>
> Thanks Kurtis and Robert.
>
> My use-case is for a telecommunications application (HTTP/2 client, 5G 
> client to be precise) which needs to send 5G (HTTP/2) requests to a server 
> at a configurable rate (TPS). 
> While the telecom industry very commonly use the word TPS (Transactions 
> Per Second), I would like to control the rate within the second i.e. if the 
> TPS is to be 2000, then I would like to spread these 2000 transactions 
> (HTTP/2 requests) over 1 second uniformly i.e. 1 request every 500 
> mico-seconds which will then result in 2000 requests in that 1 second.
> I believed that by using a time.Ticker to fire every 500 micro-seconds, I 
> would be able to achieve this outcome.
>
> Is there any other way you could suggest I do this using Go ? 
>
> On Monday, 31 January 2022 at 15:17:23 UTC+11 ren...@ix.netcom.com wrote:
>
>> Pretty much what Kurtis said. Low interval timers usually require 
>> specialized constructs if not a real time OS to efficiently (or even at 
>> all). 
>>
>> On Jan 30, 2022, at 9:16 PM, envee <neeraj....@gmail.com> wrote:
>>
>> Thanks, but I am not sure how that reference solves the issue ?
>>
>> Or are you suggesting that the only way is to use Cgo and invoke usleep 
>> to get very close to the Ticker duration specified ?
>>
>> On Monday, 31 January 2022 at 11:25:58 UTC+11 ren...@ix.netcom.com wrote:
>>
>>> See https://github.com/golang/go/issues/27707
>>>
>>> On Jan 30, 2022, at 5:50 PM, envee <neeraj....@gmail.com> wrote:
>>>
>>> Hi All,
>>>
>>> I understand this issue has been discussed in the past, and I have seen 
>>> a few comments from Ian and Russ Cox about this topic, but I could not 
>>> arrive at a conclusion about how I can make the time.Ticker send me ticks 
>>> at atleast close to the Ticker duration I specify. At the moment, I am 
>>> seeing ticks being sent at way over the specified duration especially when 
>>> I have sub-millisecond durations. 
>>> With 1ms duration, the ticker seems to be quite close to the duration 
>>> (maybe within +/-5%). I would be happier if it were within 1%, but I can 
>>> handle that.
>>>
>>> With 1 micro-second duration, the ticker sends ticks nearly 4 times 
>>> slower than expected.
>>>
>>> Here is my sample code
>>> "
>>> ti := time.NewTicker(1 * time.Millisecond)
>>> start := time.Now()
>>> for i := 0; i < 1000; i++ {
>>> <-ti.C
>>> }
>>> fmt.Printf("elapsed time = %v\n", time.Since(start))
>>> "
>>>
>>> The output is usually close to 1 second as expected (close to) when 
>>> using 1ms duration.
>>> elapsed time = 1.000159338s
>>>
>>>
>>> My code for the microsecond test is :
>>> "
>>> ti := time.NewTicker(1 * time.Microsecond)
>>> start := time.Now()
>>> for i := 0; i < 1000000; i++ {
>>> <-ti.C
>>> }
>>> fmt.Printf("elapsed time = %v\n", time.Since(start))
>>> "
>>>
>>> With this, I get the following output which shows the elapsed time close 
>>> to 4 seconds :
>>> elapsed time = 4.796662856s
>>>
>>> *Is there anyway, I can ensure ticks are sent at approximately within 5% 
>>> of my specified duration ?*
>>>
>>> I understand from time.Ticker docs that ticks will be lost if the ticker 
>>> handler cannot keep up with the ticker time.
>>>
>>> In the simple code above, I am literally doing very minimal work in each 
>>> loop iteration and that is about checking the loop condition.
>>> So I am not sure why ticks are being lost ?
>>>
>>> -- 
>>> 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...@googlegroups.com.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/golang-nuts/5f55ccf9-1478-4490-a8f4-a35a5764721dn%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/golang-nuts/5f55ccf9-1478-4490-a8f4-a35a5764721dn%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>> -- 
>> 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...@googlegroups.com.
>>
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/efa204c2-092f-46e1-abe4-8aa5c502d986n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/efa204c2-092f-46e1-abe4-8aa5c502d986n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>> -- 
> 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...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/3f9d1c36-4820-4555-a5f3-9721e661530bn%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/3f9d1c36-4820-4555-a5f3-9721e661530bn%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/2412c0ed-a01a-4c62-84c4-a7b70c79e0d9n%40googlegroups.com.

Reply via email to