-
-
Notifications
You must be signed in to change notification settings - Fork 925
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
prime? very slow #3649
Comments
Wow. Ok, I'll look into this. Definitely something wrong. |
It looks like this is never getting out of the (simple) interpreter:
|
It appears that at least part of this bad benchmark result is due to the fact that most of the hot call path is not compiling before the benchmark completes. If I force JIT to happen sooner, the numbers improve (but still don't beat MRI). It's not clear to me yet which methods are getting called. |
Ok, it looks like Ruby 2.3 improved the performance of prime.rb. JRuby 9.0.5.0 roughly matches MRI 2.2 performance, and JRuby with 2.3 stdlib roughly matches MRI 2.3 performance: Ruby 2.2 stdlib:
Ruby 2.3 stdlib
|
This is the link |
Ok, so other than the 2.2/2.3 stdlib issue, the remaining problem here is that a single long-running method does not trigger JIT. We don't have a good way to do on-stack replacement, so the best we could do would be to trigger JIT of a method that ran longer than some expectation. Below is a patch for this, but it's not really accurate because it doesn't exclude child calls. diff --git a/core/src/main/java/org/jruby/internal/runtime/methods/MixedModeIRMethod.java b/core/src/main/java/org/jruby/internal/runtime/methods/MixedModeIRMethod.java
index 2cdeaf0..7aeee01 100644
--- a/core/src/main/java/org/jruby/internal/runtime/methods/MixedModeIRMethod.java
+++ b/core/src/main/java/org/jruby/internal/runtime/methods/MixedModeIRMethod.java
@@ -97,7 +97,14 @@ public class MixedModeIRMethod extends AbstractIRMethod implements Compilable<Dy
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, args, block);
} else {
- return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, args, block);
+ long start = System.currentTimeMillis();
+ try {
+ return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, args, block);
+ } finally {
+ if ((System.currentTimeMillis() - start) > 100) {
+ context.runtime.getJITCompiler().buildThresholdReached(context, this);
+ }
+ }
}
}
@@ -132,7 +139,14 @@ public class MixedModeIRMethod extends AbstractIRMethod implements Compilable<Dy
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, block);
} else {
- return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, block);
+ long start = System.currentTimeMillis();
+ try {
+ return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, block);
+ } finally {
+ if ((System.currentTimeMillis() - start) > 100) {
+ context.runtime.getJITCompiler().buildThresholdReached(context, this);
+ }
+ }
}
}
@@ -167,7 +181,14 @@ public class MixedModeIRMethod extends AbstractIRMethod implements Compilable<Dy
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, arg0, block);
} else {
- return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, block);
+ long start = System.currentTimeMillis();
+ try {
+ return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, block);
+ } finally {
+ if ((System.currentTimeMillis() - start) > 100) {
+ context.runtime.getJITCompiler().buildThresholdReached(context, this);
+ }
+ }
}
}
@@ -202,7 +223,14 @@ public class MixedModeIRMethod extends AbstractIRMethod implements Compilable<Dy
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, arg0, arg1, block);
} else {
- return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, arg1, block);
+ long start = System.currentTimeMillis();
+ try {
+ return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, arg1, block);
+ } finally {
+ if ((System.currentTimeMillis() - start) > 100) {
+ context.runtime.getJITCompiler().buildThresholdReached(context, this);
+ }
+ }
}
}
@@ -237,7 +265,14 @@ public class MixedModeIRMethod extends AbstractIRMethod implements Compilable<Dy
if (jittedMethod != null) {
return jittedMethod.call(context, self, clazz, name, arg0, arg1, arg2, block);
} else {
- return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, arg1, arg2, block);
+ long start = System.currentTimeMillis();
+ try {
+ return INTERPRET_METHOD(context, ensureInstrsReady(), getImplementationClass().getMethodLocation(), self, name, arg0, arg1, arg2, block);
+ } finally {
+ if ((System.currentTimeMillis() - start) > 100) {
+ context.runtime.getJITCompiler().buildThresholdReached(context, this);
+ }
+ }
}
}
I'm not sure what priority to give this. |
But if try https://gist.github.com/giuan/f2176226e253d8620e0a |
0.9s versus 1.1s is not bad. And for me, the difference is greater. JRuby wins for both your
|
Well nothing in inlining branch changes when/how we JIT methods (read till end :) ), but we do keep track of checking for hot callsites via thread_polling stats. This could also be used for methods which trigger the most thread_polls. Will that be faster than 50 calls? I don't know, but it seems reasonable to me. fwiw, when inlining+profiling is enabled if we detect a site in that loopy method that needs to be inlined we actually compile the surrounding method. In that sense, how profiling works now might end up compiling earlier...assuming there is a hot ruby-only method in the loop. |
The method prime? is 20x slower then MRI.
But a method implemented by myself give the same time as MRI prime? in MRI and jruby.
I think the problem is in the library prime.
Try
Tiziano Merzi
P.S.
jruby 9.0.5.0 on MAC
The text was updated successfully, but these errors were encountered: