Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allocation-free precise and accurate clocks #2999

Closed
wants to merge 5 commits into from

Conversation

rbasralian
Copy link
Contributor

Support for using jdk.internal.misc.VM#getNanoTimeAdjustment, Instant.now(), or System.currentTimeMillis() as the source of "now" in the engine

@rbasralian rbasralian self-assigned this Oct 14, 2022
@rbasralian rbasralian marked this pull request as ready for review October 14, 2022 01:27
@cpwright
Copy link
Contributor

This change is worth a before and after JMH benchmark for getting millis/micros/nanos in a tight loop.

final RealTimeClock impl;
switch (REAL_TIME_CLOCK_SOURCE) {
case "jdk-internals":
final Iterator<RealTimeClock> it = ServiceLoader.load(RealTimeClock.class).iterator();
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you safely try jdk-internals if you have something like "default"; then degrade to instant?

test {
jvmArgs '--add-exports', 'java.base/jdk.internal.misc=ALL-UNNAMED'
systemProperty 'RealTimeClockLoader.timeSource', 'jdk-internals'
// systemProperty 'RealTimeClockLoader.timeSource', 'millis'
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally one would test both ways, though the millis and instant implementations are trivial. You might add a comment to that effect.

@devinrsmith
Copy link
Member

I've got a parallel draft PR that addresses a lot of deficiencies in our interfaces, but doesn't take any of the add-opens approach yet so I think both parts may be valuable. Will look soon. #2998

Copy link
Member

@devinrsmith devinrsmith left a comment

Choose a reason for hiding this comment

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

I believe there we will want to have some python side changes too for the embedded server case.

@@ -3,17 +3,21 @@
*/
package io.deephaven.base.clock;

import io.deephaven.clock.RealTimeClock;
import org.jetbrains.annotations.NotNull;

public interface Clock {
Copy link
Member

Choose a reason for hiding this comment

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

We should probably move this to the clock package.

}
long currentTimeNanos();

final class Null implements Clock {
Copy link
Member

Choose a reason for hiding this comment

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

enum is a better pattern IMO, but I noticed there aren't any real users of Null.

cachedNowMicros = 0;
}
@NotNull
public final RealTimeClock REAL_TIME_CLOCK = RealTimeClock.loadImpl();
Copy link
Member

Choose a reason for hiding this comment

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

public?

Comment on lines +1 to +4
/**
* Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending
*/
package io.deephaven.clock.impl;
Copy link
Member

Choose a reason for hiding this comment

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

We'll want to use a different license for clock-impl if we use the code as-is since we are using systemUTC rather directly here. That may not be true if we change our strategy for calling VM

* {@link VM#getNanoTimeAdjustment}), between the current time and midnight, January 1, 1970 UTC.
*/
@Override
public long currentTimeNanos() {
Copy link
Member

Choose a reason for hiding this comment

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

We should test out some different strategies. We may be able to get away w/ simply:

return VM.getNanoTimeAdjustment(0);

/**
* Created by rbasralian on 10/13/22
*/
public final class JavaInstantRealTimeClock implements RealTimeClock {
Copy link
Member

Choose a reason for hiding this comment

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

can be enum w/ single INSTANCE.

import java.util.Optional;
import java.util.ServiceLoader;

public interface RealTimeClock {
Copy link
Member

Choose a reason for hiding this comment

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

We should probably have RealTimeClock extends Clock


test {
jvmArgs '--add-exports', 'java.base/jdk.internal.misc=ALL-UNNAMED'
systemProperty 'RealTimeClockLoader.timeSource', 'jdk-internals'
Copy link
Member

Choose a reason for hiding this comment

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

IMO, we should have an "escape" hatch, but the majority of cases shouldn't need to specify the system property IMO.

runtimeOnly project(':clock-impl')
}
extraJvmArgs += ['--add-exports', 'java.base/jdk.internal.misc=ALL-UNNAMED']
extraJvmArgs += ['-DRealTimeClockLoader.timeSource=jdk-internals']
Copy link
Member

Choose a reason for hiding this comment

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

again, this should be implicit based on the classpath for the majority of use-cases.

@@ -43,6 +43,8 @@ Finally, Gradle can be used to update the build and run the application in a sin
`--add-opens java.management/sun.management=ALL-UNNAMED`. To disable this, set the gradle property `includeHotspotImpl`
to `false`.

... also clockImpl and java.base/jdk.internal.misc=ALL-UNNAMED
Copy link
Member

Choose a reason for hiding this comment

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

better doc.

@devinrsmith
Copy link
Member

Benchmarking nanoTime() is hard. It may be a little better w/ REALTIME clocks b/c they don't have to be monotonic.

See https://shipilev.net/blog/2014/nanotrusting-nanotime/

@rbasralian
Copy link
Contributor Author

See #2998

@rbasralian rbasralian closed this Oct 24, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Oct 24, 2022
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants