www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can I get the time "Duration" in "nsecs" acurracy?

reply rempas <rempas tutanota.com> writes:
I'm reading the library reference for 
[core.time](https://dlang.org/phobos/core_time.html#Duration) and 
It says that the duration is taken in "hnsecs" and I cannot 
understand if we can change that and choose the precision. Does 
anyone know if we can do that?
Jul 09
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 9 July 2021 at 20:43:48 UTC, rempas wrote:
 I'm reading the library reference for 
 [core.time](https://dlang.org/phobos/core_time.html#Duration) 
 and It says that the duration is taken in "hnsecs" and I cannot 
 understand if we can change that and choose the precision. Does 
 anyone know if we can do that?
It is stored internally in "hnsecs", but you can convert it to other units using the `total` method [1]; for example, `myDuration.total!"nsecs"`. [1] https://dlang.org/phobos/core_time.html#.Duration.total
Jul 09
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 7/9/21 1:54 PM, Paul Backus wrote:
 On Friday, 9 July 2021 at 20:43:48 UTC, rempas wrote:
 I'm reading the library reference for 
 [core.time](https://dlang.org/phobos/core_time.html#Duration) and It 
 says that the duration is taken in "hnsecs" and I cannot understand if 
 we can change that and choose the precision. Does anyone know if we 
 can do that?
It is stored internally in "hnsecs", but you can convert it to other units using the `total` method [1]; for example, `myDuration.total!"nsecs"`. [1] https://dlang.org/phobos/core_time.html#.Duration.total
Yes but the resolution seems not to be better than 100 nsecs. A quick research reveals a better resolution is not possible with common hardware on at least Linux. The following program always prints multiples of 100 on my Mint OS: import std.stdio; import core.thread; import std.datetime.stopwatch; void main() { auto sw = StopWatch(); sw.start(); foreach (_; 0..10) { Thread.sleep(0.nsecs); writefln("%,s", sw.peek.total!"nsecs"); } } Ali
Jul 09
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 7/9/21 5:04 PM, Ali Çehreli wrote:
 On 7/9/21 1:54 PM, Paul Backus wrote:
 On Friday, 9 July 2021 at 20:43:48 UTC, rempas wrote:
 I'm reading the library reference for 
 [core.time](https://dlang.org/phobos/core_time.html#Duration) and It 
 says that the duration is taken in "hnsecs" and I cannot understand 
 if we can change that and choose the precision. Does anyone know if 
 we can do that?
It is stored internally in "hnsecs", but you can convert it to other units using the `total` method [1]; for example, `myDuration.total!"nsecs"`. [1] https://dlang.org/phobos/core_time.html#.Duration.total
Yes but the resolution seems not to be better than 100 nsecs. A quick research reveals a better resolution is not possible with common hardware on at least Linux. The following program always prints multiples of 100 on my Mint OS: import std.stdio; import core.thread; import std.datetime.stopwatch; void main() {   auto sw = StopWatch();   sw.start();   foreach (_; 0..10) {     Thread.sleep(0.nsecs);     writefln("%,s", sw.peek.total!"nsecs");   } }
You can get better than hnsecs resolution with `core.time.MonoTime`, which can support whatever the OS supports. However, `Duration` and `SysTime` are stored in hnsecs for a very specific reason -- range. Simply put, if you have a 64-bit integer, and you picked nanoseconds as the unit, you can store only 585 years of range. 10 ns gives you 5850 years, and 100 ns gives you 58k years. That should be good enough for all but the most esoteric calculations (given that a `Duration` is signed, this gives a range of roughly -29k years to 29k years). Note also that hnsecs is the base unit for Windows high precision clocks, though their epoch is year 1600 instead of year 0. -Steve
Jul 09
parent Bruce Carneal <bcarneal gmail.com> writes:
On Saturday, 10 July 2021 at 01:11:28 UTC, Steven Schveighoffer 
wrote:
 

 You can get better than hnsecs resolution with 
 `core.time.MonoTime`, which can support whatever the OS 
 supports.

 However, `Duration` and `SysTime` are stored in hnsecs for a 
 very specific reason -- range. Simply put, if you have a 64-bit 
 integer, and you picked nanoseconds as the unit, you can store 
 only 585 years of range. 10 ns gives you 5850 years, and 100 ns 
 gives you 58k years. That should be good enough for all but the 
 most esoteric calculations (given that a `Duration` is signed, 
 this gives a range of roughly -29k years to 29k years).

 Note also that hnsecs is the base unit for Windows high 
 precision clocks, though their epoch is year 1600 instead of 
 year 0.
Nice summary. hnsecs is a little weird but defensible given the range argument. Down the road we might add a nanosecond timeline abstraction based on TAI with zero set to 1972 (when UTC was aligned with TAI IIUC). Range issues could be addressed by animating the long dormant cent. Any precision issues could be handled with fixed point pairs. Doubles across the same timeline would work for casual applications.
Jul 10
prev sibling parent reply rempas <rempas tutanota.com> writes:
On Friday, 9 July 2021 at 21:04:42 UTC, Ali Çehreli wrote:
 On 7/9/21 1:54 PM, Paul Backus wrote:
 [...]
Yes but the resolution seems not to be better than 100 nsecs. A quick research reveals a better resolution is not possible with common hardware on at least Linux. The following program always prints multiples of 100 on my Mint OS: import std.stdio; import core.thread; import std.datetime.stopwatch; void main() { auto sw = StopWatch(); sw.start(); foreach (_; 0..10) { Thread.sleep(0.nsecs); writefln("%,s", sw.peek.total!"nsecs"); } } Ali
So it's an OS thing? C++ with "std::chrono" can show me less than 1 hnsec (100 nanoseconds) accuracy.
Jul 09
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 7/9/21 11:28 PM, rempas wrote:

 So it's an OS thing?
Don't listen to me on this. :) A quick search yesterday made me believe you need kernel support as well. Even if so, I would imagine modern kernel on modern hardware should work. Ali
Jul 10
prev sibling parent reply rempas <rempas tutanota.com> writes:
On Friday, 9 July 2021 at 20:54:21 UTC, Paul Backus wrote:
 On Friday, 9 July 2021 at 20:43:48 UTC, rempas wrote:
 I'm reading the library reference for 
 [core.time](https://dlang.org/phobos/core_time.html#Duration) 
 and It says that the duration is taken in "hnsecs" and I 
 cannot understand if we can change that and choose the 
 precision. Does anyone know if we can do that?
It is stored internally in "hnsecs", but you can convert it to other units using the `total` method [1]; for example, `myDuration.total!"nsecs"`. [1] https://dlang.org/phobos/core_time.html#.Duration.total
It doesn't work for me. I have the following code: ``` MonoTime start = MonoTime.currTime(); // Doing stuff MonoTime end = MonoTime.currTime(); Duration dur = end - start; dur = dur.total!"nsecs"; ``` and I get the following error message: "Error: cannot implicitly convert expression \`dur.total()\` of type \`long\` to \`Duration`"
Jul 09
next sibling parent jfondren <julian.fondren gmail.com> writes:
On Friday, 9 July 2021 at 21:13:02 UTC, rempas wrote:
 ```
 Duration dur = end - start;
 dur = dur.total!"nsecs";
 ```
What are you trying to do, assigning a nanosecond value to a Duration? The Duration already has that many nanoseconds in it.
 and I get the following error message:

 "Error: cannot implicitly convert expression \`dur.total()\` of 
 type \`long\` to \`Duration`"
Jul 09
prev sibling next sibling parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Friday, 9 July 2021 at 21:13:02 UTC, rempas wrote:
 On Friday, 9 July 2021 at 20:54:21 UTC, Paul Backus wrote:
 On Friday, 9 July 2021 at 20:43:48 UTC, rempas wrote:
 I'm reading the library reference for 
 [core.time](https://dlang.org/phobos/core_time.html#Duration) 
 and It says that the duration is taken in "hnsecs" and I 
 cannot understand if we can change that and choose the 
 precision. Does anyone know if we can do that?
It is stored internally in "hnsecs", but you can convert it to other units using the `total` method [1]; for example, `myDuration.total!"nsecs"`. [1] https://dlang.org/phobos/core_time.html#.Duration.total
It doesn't work for me. I have the following code: ``` MonoTime start = MonoTime.currTime(); // Doing stuff MonoTime end = MonoTime.currTime(); Duration dur = end - start; dur = dur.total!"nsecs"; ``` and I get the following error message: "Error: cannot implicitly convert expression \`dur.total()\` of type \`long\` to \`Duration`"
You cannot change the precision of `Duration`, it always counts in multiples of 100 nsecs. You can count how many multiples of other units fit into the same `Duration` using `total`, but it will just return a number, not a “converted” `Duration`. `toString` will produce an easy readable string (more or less), as in https://run.dlang.io/is/baqKLG, where “hnsec” is the smallest unit. If you think hectonanosecond is a weird unit, then [you are not alone](https://forum.dlang.org/post/pwotyniksrskdzmeafin forum.dlang.org), and it [has been pointed out](https://forum.dlang.org/post/khppfxsyfefjksvrimkx forum.dlang.org) that it does not comply with SI. — Bastiaan.
Jul 09
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 7/9/21 5:13 PM, rempas wrote:
 On Friday, 9 July 2021 at 20:54:21 UTC, Paul Backus wrote:
 On Friday, 9 July 2021 at 20:43:48 UTC, rempas wrote:
 I'm reading the library reference for 
 [core.time](https://dlang.org/phobos/core_time.html#Duration) and It 
 says that the duration is taken in "hnsecs" and I cannot understand 
 if we can change that and choose the precision. Does anyone know if 
 we can do that?
It is stored internally in "hnsecs", but you can convert it to other units using the `total` method [1]; for example, `myDuration.total!"nsecs"`. [1] https://dlang.org/phobos/core_time.html#.Duration.total
It doesn't work for me. I have the following code: ``` MonoTime start = MonoTime.currTime(); // Doing stuff MonoTime end = MonoTime.currTime(); Duration dur = end - start; dur = dur.total!"nsecs"; ``` and I get the following error message: "Error: cannot implicitly convert expression \`dur.total()\` of type \`long\` to \`Duration`"
BTW `Duration` is truncating here. `MonoTime` stores its values in implementation-defined ticks, which can be nanoseconds or any other thing that the specific clock uses. Whereas `Duration` uses strictly hnsecs. If you want to get sub-hnsec resolution, use the `ticks` member of `MonoTime` and `ticksPerSecond` and do the math for the units. See the warning [here](https://dlang.org/phobos/core_time.html#.MonoTimeImpl.opBinary). -Steve
Jul 11
prev sibling parent dangbinghoo <dangbinghoo gmail.com> writes:
On Friday, 9 July 2021 at 20:43:48 UTC, rempas wrote:
 I'm reading the library reference for 
 [core.time](https://dlang.org/phobos/core_time.html#Duration) 
 and It says that the duration is taken in "hnsecs" and I cannot 
 understand if we can change that and choose the precision. Does 
 anyone know if we can do that?
don't expecting 1ns when you running software on GHz clocking CPU running with `normal-linux`. 1ns means 1Ghz. and common x86 cpu runs at 1-4Ghz, and in this situation, only 10ns will be expected from base-metal software(OS). as `normal-linux` is not real-time at all, 100ns is logical. thanks! dbh.
Jul 12