Skip to content

Implement hrtime()#2368

Closed
kelunik wants to merge 8 commits intophp:masterfrom
kelunik:hrtime
Closed

Implement hrtime()#2368
kelunik wants to merge 8 commits intophp:masterfrom
kelunik:hrtime

Conversation

@kelunik
Copy link
Copy Markdown
Member

@kelunik kelunik commented Feb 6, 2017

I have no idea whether we need something for configure, AFAIK everything we support is either Windows, Apple or POSIX compatible.

@weltling
Copy link
Copy Markdown

weltling commented Feb 6, 2017

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Feb 6, 2017

@weltling What's the use case for directly using ticks? Most points should be solved with the latest commit. :)

I chose hrtime() as it's also used in Node and it aligns well with the microtime naming.

@krakjoe krakjoe added the Feature label Feb 6, 2017
Copy link
Copy Markdown

@weltling weltling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it is a new stuff, some more obvious function names can be introduced. At least the "monotonic" is one of the useful keywords. Don't care much actually, but not everyone programs node :)

Also, while nanoseconds are good, some systems can deliver better, especially non POSIX. Or even, one could use the actual ticks directly, to implement a custom time measurement. On fast systems it's a quite realistic scenario, even with some overhead in PHP. For that purpose the actual low level units can be useful, or an explicit time unit argument. But yes, ns monotonic time is a good start, anyway, if no one cares about more.

There is an article about the portability, which i found useful some time ago http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking while implementing the PECL hrtime. Clear, there's no good chance to test all the systems, at least what should be ensured is - that there's a robust fallback on both compilation and run time.

Thanks.

char buffer[64];
int result = 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revoke the WS change.

var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
filters.c proc_open.c streamsfuncs.c http.c password.c \
random.c,,,
random.c hrtime.c,,,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should check for symbols and mark a fallback case, maybe falling back to gettimeofday() or anything better in the code. Specifically for POSIX - it should check for CLOCK_MONOTONIC define, as there can be variations in the implementations. I think, it's even better to check for different platforms explicitly - BSD, Solaris for sure, and maybe some other.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I know, CLOCK_MONOTONIC is available on FreeBSD, OpenBSD, Solaris, AIX, etc. There are just differences for CLOCK_MONOTONIC_RAW / CLOCK_MONOTONIC_PRECISE etc.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least one platform doesn't have it, as per the linked blog. Edge cases, still they should be covered them if they're known.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, HP-UX doesn't seem to support it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added support for HP-UX just now. Any other edge cases we know of? I think the checks should be fine now with the conditional definition?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, i thought we'd rather exclude it in configure, but works this way, too. Except probably only a few can test it :/ There are no cases, i'd be aware of otherwise.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not a so-easy subject to takle. Systems tend to be pretty different in their API for time measurement.
Also, you should have a read at http://nadeausoftware.com/articles/2012/03/c_c_tip_how_measure_cpu_time_benchmarking

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jpauli That's talking about CPU time for benchmarking, that's not the use case I have. While benchmarking is another possible use case for hrtime(), the reason I created this PR and am interested in hrtime() is for event loops. I'm not even interested in a nanosecond resolution, it just happens to be provided. Milliseconds would be enough for my use case.

/* {{{ */
PHP_MINIT_FUNCTION(hrtime)
{
if (_timer_init()) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For whatever reason, if the initialization has failed, the whole should fallback to something.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fail back to what? Depends on what we want to guarantee for this function. If we want to guarantee no jumps and monotony, we can't fallback to anything.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't want to make the timer a hard requirement we can either a) only register the function is the functionality is available or b) throw an exception if the function is called.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thought was falling back to getttimeofday() or alike, as it is supposed to be a rare case, and otherwise it needs one more condition check. Fine with being strict and exception, it solves the case as well.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case we won't ever find the missing platforms and just think those are supported.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jpauli If it fails in MINIT it fails with a fatal error. It doesn't make sense to continue if the initialization already failed. The issue with a notice or warning is that you need a dummy return value and nobody will check the return value.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was talking about the case where we would replacing a failing init call by a gettimeofday() call. In such a case, we must return SUCCESS, and throw a Notice.

Copy link
Copy Markdown
Member Author

@kelunik kelunik Feb 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no such case. If it can't use a monotonic time but compiled fine, it will result in a fatal error. It won't fall back to gettimeofday().

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I thought we were talking about a possible replacement by gtod() if failing , so we forget such an idea.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weltling wanted to do that. I don't want to do that, as it breaks the guarantee of monotony and might jump, while hrtime() usually doesn't do that.

#elif TIMER_PLATFORM_POSIX

struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
clock_gettime( CLOCK_MONOTONIC, &ts );
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return values should be checked.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we support Windows < XP?

Copy link
Copy Markdown

@weltling weltling Feb 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, for 7.2 is also win7/2008r2 is the lowest, see UPGRADING.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok fine, then we don't need any check on Windows, as it's guaranteed to always return true then.

return;
}

// Use double to avoid integer overflows as we don't know the order of magnitude
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No C++ comments please :)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}

// Use double to avoid integer overflows as we don't know the order of magnitude
RETURN_LONG((uint64_t) ((double) 1000000000 * _timer_current() / _timer_freq));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about 32 bit systems?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On 32-bit it should be fine to return double, while on 64-bit zend_long were ok. For simplicity, it might be ok to just deal with double only.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case we should use double only.

<?php

$time = hrtime();
usleep(500000);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing with any kind of sleep is not reliable, sleep might freeze the process on some system. You might be much better served checking some block execution dynamically, and comparing with another timing implementation like microtime(). Here fe what i invented for the hrtime ext http://svn.php.net/viewvc/pecl/hrtime/trunk/tests/helper.inc?view=markup . In general, it also sohuld be compared to an existing time implementation in PHP, to ensure the compatibility and correctness.

Thanks.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I check for the difference now, is that fine?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But still based on sleep ;)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How might sleep freeze some systems? Adding random computations doesn't guarantee it waits at least the time we test against.

Copy link
Copy Markdown

@weltling weltling Feb 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not systems, but process on some system. Sleep functions don't guarantee the exact time you pass, and the process needs to wake up, etc. The resolution of the sleep function is not guaranteed, a busy wait is more reliable for this purpose.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it measures the difference now, taking longer isn't a concern.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, this thread is related to an outdated diff.

Thanks.


uint64_t current_time = _timer_current();

if (current_time == -1) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please wrap with UNEXPECTED().

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. :-)

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Feb 6, 2017

@weltling What do you think about the function name now? Should we keep hrtime or change it to something else? It does no longer return nanoseconds now but seconds as float now.

Also, I think the module init conflicts with your extension now, no?

@weltling
Copy link
Copy Markdown

weltling commented Feb 6, 2017

@kelunik Oh, didn't check yet, so you don't return the nanoseconds anymore? Just nanoseconds might be simpler for the user space, probably. But the name imho should still be more descriptive, maybe at least monotonic_<something>. for the reasons expressed before. A class could be even more flexible even, as @Fleshgrinder suggests, however one dedicated function is much simpler and faster. Please, lets leave these points to the further comments and discussion.

Ofc, it would be nice to avoid the conflict with the hrtime ext. I was already thinking about some timer with callback implementation, still not sure when i could come to it :) The submodule could be renamed, if possible.

Thanks.

@jpauli
Copy link
Copy Markdown
Member

jpauli commented Feb 9, 2017

If we just publish one function, there is no need for a class.

I would call it hrtime() , like in other languages.
We have microtime() , so ... microtime() <-> hrtime() , we stay in the same meaning.

Also, I would give the user the choice of the return value : wether he wants seconds as a float, or nanoseconds as an integer (or float if overflow).

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Feb 9, 2017

@jpauli As others already noted, toggling return types depending on flags is bad and should be avoided. It's better to introduce other functions instead.

Also, I would give the user the choice of the return value : wether he wants seconds as a float, or nanoseconds as an integer (or float if overflow).

Having a return type not only depending on the input parameters, but also on the architecture, is a pretty bad thing to have. It makes code more prone to errors and I'd say it doesn't have any advantage single over always using one type.

@jpauli
Copy link
Copy Markdown
Member

jpauli commented Feb 9, 2017

Yes I read the thread. My link was about the different constants, MONOTONIC vs MONOTONIC_RAW , f.e
Nanoseconds would be great, so the function can cover different use cases (event loops, profiling, etc...)

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Feb 9, 2017

@jpauli Different use cases should probably have different functions. Event loops probably want MONOTONIC while for profiling you probably want MONOTONIC_RAW.

@weltling
Copy link
Copy Markdown

weltling commented Feb 9, 2017

@kelunik I was thinking a bit further as well. In the current form it doesn't look like nanoseconds everywhere, only in POSIX variant. The ticks/frequency will deliver possibly better or worse, so this can have unexpected effects for comparisons. The specification should be strict to follow - the ns precision is what is available on the most platforms currently, so ns precision should be delivered.

Also, it might less error prone, if the function delivers the number of nanoseconds, this will reduce bugs with the fraction part. Or regarding the other idea about [seconds, nanoseconds] - this might work, need some evaluation. The accuracy is unlikely to be <= ns. Or what do your tests show on the implementation?

With the module name - you can rename it to something like hrtime_mod. The name is not visible to outside anyway, but will help to avoid the module conflict with pecl hrtime.

I'm getting some time to test this patch in the next weeks, will come back with the results yet.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Feb 10, 2017

@weltling According to https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx, QueryPerformanceCounter is the API to use and it only delivers <µs, it doesn't say nanoseconds.

Also, it might less error prone, if the function delivers the number of nanoseconds, this will reduce bugs with the fraction part.

Which kind of bugs do you have in mind?

Or what do your tests show on the implementation?

I didn't extensively test the accuracy yet.

With the module name - you can rename it to something like hrtime_mod. The name is not visible to outside anyway, but will help to avoid the module conflict with pecl hrtime.

Sure, maybe just phphrtime?

@weltling
Copy link
Copy Markdown

@kelunik the link is exactly what i'm talking about. While POSIX explicitly delivers nanoseconds, Windows and Mac APIs deliver ticks. In practice, on fast machines and suitable HW source, it could be even picosecond resolution or better, at least on Windows. Or it could be worse than ns on slower machine or VM. From the doc, the Mac API works same way, and in general it's achievable by utilizing the corresponding registers directly like with inline ASM. Now, if the whole tick thing delivers a better resolution, and we don't explicitly bring it to nanoseconds - users don't know the exact time unit and the comparison of such values doesn't guarantee the crossplatform conformance. Say, comparing 1001ps and 1002ps would already give another comparison result than if both were truncated to ns.

This hangs together with the other possible issue mentioned, by delivering a floating point value it can cause additional rounding errorr. Say, it'd deliver 1.000000001s (one second and one nanosecond) vs [1, 1] as same. IMO, this should be taken into evaluation, because there might be enough gap to compose such output. It is indeed about producing, as for the consumption the processing time might not matter much. Some cases I have in mind with this.

  • as initial motivation, the event loop. If you only care about the runtime under a second duration, separate nanoseconds part is useful
  • for performance testing, even for duration longer than one second, it doesn't matter at all

It'd be great to hear some more use cases, as this helps to form a better API in the end. So far, also looking at the other implementations including the node one - seems it might be acceptable to produce a more suitable output, whereby many APIs differ in the way they are used in different languages.

phphrtime as module name were probably ok, it really doesn't matter much as it's internal only.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Feb 10, 2017

Now, if the whole tick thing delivers a better resolution, and we don't explicitly bring it to nanoseconds - users don't know the exact time unit and the comparison of such values doesn't guarantee the crossplatform conformance.

The time unit is fixed (either seconds or nanoseconds), the only thing that's not guaranteed is the accuracy. How do you want to solve that?

This hangs together with the other possible issue mentioned, by delivering a floating point value it can cause additional rounding errorr.

We can also make it 100% the same as microtime() with a flag.

as initial motivation, the event loop. If you only care about the runtime under a second duration, separate nanoseconds part is useful

Event loops usually care about millisecond resolution, not seconds, so we have to scale the return value either way.

for performance testing, even for duration longer than one second, it doesn't matter at all

For performance testing with high accuracy with short durations you want CLOCK_MONOTONIC_RAW, while for event loops you also have longer durations like minutes, where CLOCK_MONOTONIC is more suitable.

But for the usual performance testing, both should probably be fine.

@weltling
Copy link
Copy Markdown

Now, if the whole tick thing delivers a better resolution, and we don't explicitly bring it to nanoseconds - users don't know the exact time unit and the comparison of such values doesn't guarantee the crossplatform conformance.

The time unit is fixed (either seconds or nanoseconds), the only thing that's not guaranteed is the accuracy. How do you want to solve that?

Exactly, the time unit needs to be specified and followed strictly. In the current PR implementation, Mac and Windows don't deliver ns exactly. The combination ticks/frequency does not give nanoseconds back, that's what i tried to illustrate in the previous post.

One simple solution that i'm doing in the hrtime, which however can be improved, ist to do 10^9*(ticks/frequency). This will deliver the number of nanoseconds in the decimal part, an improvement to this were to just abandon the floating point part. Comparing such values with the fractional part .0 would significatly minimize rounding mistakes. Or, if having a float with seconds.nanoseconds, this truncation were to follow as well, so then one could for example do by sense floor(10^9*(ticks/frequency))/10^9.

Another solution is with the [seconds, nanoseconds], till 2038 it'll be still ok to deliver them as integers both so would be good for 32-bit anyway.

Event loops usually care about millisecond resolution, not seconds, so we have to scale the return value either way.

Yeah, in the most situations, the milliseconds is the most reliable resolution even today :) Just if we say "high resolution", it obliges somehow :) Itself, monotonic time in milliseconds has probably the most reliable APIs on any platforms.

For performance testing with high accuracy with short durations you want CLOCK_MONOTONIC_RAW, while for event loops you also have longer durations like minutes, where CLOCK_MONOTONIC is more suitable.

I was more talking about the consuming part with regard to the overhead of hrtime() itself. One thing is that it has to be fast, but what we were discussing is the additional overhead to produce the output. And here, the actual accuracy might play good, because the gap can be big enough for some additional instructions to produce the desired output. Evermore it can be the case on the systems with the better time resolution and accuracy. Once hrtime() delivered, the actual performance evaluation time doesn't matter. For the POSIX part - yep, probably it could be reconsidered to use CLOCK_MONOTONIC_RAW where possible and if needed, just MONOTONIC seems fine enough, though.

So as for me, for one - we need to ensure all the output is strictly nanoseconds, as by the specification. And then - to consider the output format that would fit for as much as possible generic cases. Regarding the microtime() compatibility - IMHO returning a string were not suitable for today's terms. But maybe indeed, either array [s, ns] or some kind of float, or even just one of those.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Feb 10, 2017

Exactly, the time unit needs to be specified and followed strictly. In the current PR implementation, Mac and Windows don't deliver ns exactly. The combination ticks/frequency does not give nanoseconds back, that's what i tried to illustrate in the previous post.

One simple solution that i'm doing in the hrtime, which however can be improved, ist to do 10^9*(ticks/frequency).

I don't understand, you say ticks/frequency doesn't work and then propose ticks/frequency as solution? Yes, it currently returns it in seconds (without 10^9*), but that doesn't matter, it is a fixed unit. And I currently chose seconds to align with microtime.

@weltling
Copy link
Copy Markdown

I said, that ticks/frequency is not ns aligned, that's what i said. How is one supposed to compare values of "some fixed unit"? We are talking about the specification, which says "the function always delivers ns".

Thanks.

@weltling
Copy link
Copy Markdown

weltling commented Mar 7, 2017

@kelunik ping, what's your plan to resolve the open questions?

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Mar 7, 2017

@weltling Could you summarize the open questions or do I have to read through the entire thread? Can't remember the open points on top of my head right now.

@weltling
Copy link
Copy Markdown

weltling commented Mar 8, 2017

@kelunik Yes, please check through the notes yet. For what I care, there are at least these

  • ensure the output is ns aligned
  • for POSIX, usage of CLOCK_MONOTONIC_RAW
  • possibility for an argument to have either float or array with [s, ns]

Needs evaluation before and tests after the implementation.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Mar 8, 2017

ensure the output is ns aligned

What do you mean with "aligned"? Accuracy?

for POSIX, usage of CLOCK_MONOTONIC_RAW

That's not what libuv uses and not what I'd use for an event loop.

possibility for an argument to have either float or array with [s, ns]

I'm not sure, but I think I prefer consistency with microtime over using an array here.

@weltling
Copy link
Copy Markdown

weltling commented Mar 8, 2017

What do you mean with "aligned"? Accuracy?

Precision. That's what was discussed in the posts about - ticks/freq is arbitrary. Delivering nanoseconds means it is rounded to the exact precision, disregarding whether system would deliver worse/better.

That's not what libuv uses and not what I'd use for an event loop.

Well, CLOCK_MONOTONIC_RAW would be suitable for any purpose, i think that's why it was mentioned earlier. For long running it might be also better, as it has no NTP shifts. But anyway, if getting better perf measurement support, while not hurting other things, why not?

I'm not sure, but I think I prefer consistency with microtime over using an array here.

That's where an evaluation were needed. Creating an array would take time of course, but if there's a gap in the accuracy, it would be fine. Would have to check on a number of real systems and vms, as even if it'd affect the actual result, it could be still acceptable.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Mar 13, 2017

@weltling I think we should split the function into two functions. Event loops have significantly other priorities than performance measurement. For event loops, CLOCK_MONOTONIC_COARSE is actually usually enough, and also cheaper.

@weltling
Copy link
Copy Markdown

In that case i'd suggest to leave another function for another PR, to hold the effort and impact manageable here. Could you please list, what is essentially different for event loops?

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Mar 13, 2017

@weltling Event loops don't need the high accuracy, they just need the monotony. CLOCK_MONOTONIC_COARSE can be cheaper than CLOCK_MONOTONIC. I don't know whether the difference actually matters, probably not.

@weltling
Copy link
Copy Markdown

The man page says CLOCK_MONOTONIC_COARSE is arch dependent, probably it's not worth it if it'd lead to some compilcation of the setup stuff. CLOCK_MONOTONIC_RAW seems close to performance counter on Windows. After doing some research, there was some issues with CLOCK_MONOTONIC on older kernels, which seem to be not reproducible today. Probably in the end - we're fine with just CLOCK_MONOTONIC for the start, could rethink this later when the function is used in the real world and there is some feedback.

Thanks.

@krakjoe
Copy link
Copy Markdown
Member

krakjoe commented Jul 12, 2017

Can we know the status of this patch please ?

/cc @weltling @kelunik

@weltling
Copy link
Copy Markdown

@krakjoe there are two outstanding points, from what i remember. One should be fixed is about delivering the exact nanoseconds. The other one, about delivering [s, ns] was still not discussed to the end.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Jul 15, 2017

@weltling I don't care about delivering exact nanoseconds. If you want that, feel free to deliver a patch. I only care about millisecond resolution.

I'd be fine with just mirroring microtime() and exposing it as monotonictime().

@weltling
Copy link
Copy Markdown

@kelunik if you decide to change the spec, then it should be round to exact ms. Delivering numbers that the system just gives is unreliable as they can differ on different systems. In the end that would cause undefined behaviors and users likely having to do the rounding themselves. Same about microtime alike array - in the practical sense delivering ints can overwhelm a possible impact, because double comparison is unreliable.

It's also too bad this patch was placed on hold since at least three months, as the feature freeze comes. If I even had time to work on it, the time for a proper testing is simply doesn't exist. I still can do some follow ups on this patch at some later point, if you're not interested anymore.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Nov 11, 2017

@weltling I don't see the issue with unreliability, could you show a code example and how it would fail due to unreliability?

@weltling
Copy link
Copy Markdown

@kelunik see #2368 (comment) and follow up.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Nov 11, 2017

@weltling What really matters is the unit, and the unit is the same across all systems, because of https://msdn.microsoft.com/de-de/library/windows/desktop/ms644905(v=vs.85).aspx

@weltling
Copy link
Copy Markdown

That's exactly the point. When you fuel your car, you use a well defined unit to measure it. Same way, if you deliver time, nanosecond is what fits best nowadays. If you perhaps took the trouble to read some further details on https://msdn.microsoft.com/de-de/library/windows/desktop/dn553408(v=vs.85).aspx#resolution__precision__accuracy__and_stability , other platforms have no much difference on that.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Nov 11, 2017

I read it, it doesn't make anything clearer. My code already delivers a known unit, seconds. Delivering nanoseconds always isn't possible due to 32 bit support, no?

@weltling
Copy link
Copy Markdown

@kelunik well, then i'd urge you to investigate more and to do some practical testing. One resource i could mention yet were http://www.windowstimestamp.com/description. The theory is nice by unfortunately doesn't match the reality when it comes to platforms, hardware, virtualization and more. Anything above nanosecond either doesn't matter and/or is not reliable nowadays. Cutting off is done in microtime() as well, in regard to the other question also that stands out, about delivering [s, ns] as integer.

There was similar discussions around 5.4/5.5 times, where people suggested to do strange things that wouldn't work reliably per se, you might lookup those as well. Fe if as in the doc, if on some system the tick interval 320ns, you might have hard times trying to compare twos subsequent results. If you don't cut off anything above ns, you might think a rounding error is a real result, because you want to deliver a float. Doing strange things doesn't really help for quality. That's why the ext/hrtime came to life, actually.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Nov 12, 2017

Again, I don't care about benchmarking nanoseconds with it. I just care about a monotonic time source.

If you want to use that function for other purposes, please do the changes on top of the PR later then.

@weltling
Copy link
Copy Markdown

Referring to this #2368 (comment) - so you see there is an unreliability? Then it's your call to not to care. Every PR has surrounding aspects, being ignorant about them doesn't help for quality, it's not about what one wants ;) The title of this PR is however "Implement hrtime()". As mentioned already #2368 (comment), I'm going to finish this properly when have time then, the most work is already done.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Nov 12, 2017

No, I don't. That's why I'm not going to put further work into this. You seem to know exactly what's missing.

I'm totally fine renaming the PR to monotonic_time()

@weltling
Copy link
Copy Markdown

@kelunik please check #2976.

Thanks.

@kelunik
Copy link
Copy Markdown
Member Author

kelunik commented Dec 16, 2017

Closing in favor of #2976.

@kelunik kelunik closed this Dec 16, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants