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

stdlib benchmarks regression: DataflowError with stack #10702

Closed
Akirathan opened this issue Jul 29, 2024 · 12 comments · Fixed by #11153
Closed

stdlib benchmarks regression: DataflowError with stack #10702

Akirathan opened this issue Jul 29, 2024 · 12 comments · Fixed by #11153
Assignees
Labels
--low-performance --regression Important: regression -compiler -libs Libraries: New libraries to be implemented p-high Should be completed in the next sprint

Comments

@Akirathan
Copy link
Member

There are some big regressions in *...Map_Id_All_Errors benchmarks. In some cases, even 500%.

Screenshots:
image

image

image

https://enso-org.github.io/engine-benchmark-results/stdlib-benchs.html#org_enso_benchmarks_generated_Map_Error_Benchmark_Vector_ignore_Map_Id_All_Errors


@Akirathan Akirathan added p-high Should be completed in the next sprint -compiler -libs Libraries: New libraries to be implemented --low-performance --regression Important: regression labels Jul 29, 2024
@Akirathan Akirathan self-assigned this Jul 29, 2024
@Akirathan
Copy link
Member Author

Blocked by #10706. Running Enso-only benchmarks gives nonsense values. For example:

$ enso --run test/Benchmarks Map_Id_All_Errors
Benchmarking 'Map_Error_Benchmark_Vector_ignore.Map_Id_All_Errors' with configuration: [warmup={3 iterations, 3 seconds each}, measurement={3 iterations, 3 seconds each}]
Warmup duration:    18805 ms
Warmup invocations: 1
Warmup avg time:    18725.603 ms (+-NaN)
Measurement duration:    17741 ms
Measurement invocations: 1
Measurement avg time:    17734.925 ms (+-NaN)
Benchmark 'Map_Error_Benchmark_Vector_ignore.Map_Id_All_Errors' finished in 36563.609 ms
Benchmarking 'Map_Error_Benchmark_Vector_report_warning.Map_Id_All_Errors' with configuration: [warmup={3 iterations, 3 seconds each}, measurement={3 iterations, 3 seconds each}]
Warmup duration:    15681 ms
Warmup invocations: 1
Warmup avg time:    15674.661 ms (+-NaN)
Measurement duration:    15361 ms
Measurement invocations: 1
Measurement avg time:    15354.849 ms (+-NaN)
Benchmark 'Map_Error_Benchmark_Vector_report_warning.Map_Id_All_Errors' finished in 31045.643 ms
Benchmarking 'Map_Error_Benchmark_Array_ignore.Map_Id_All_Errors' with configuration: [warmup={3 iterations, 3 seconds each}, measurement={3 iterations, 3 seconds each}]
Warmup duration:    16347 ms
Warmup invocations: 1
Warmup avg time:    16342.969 ms (+-NaN)
Measurement duration:    15964 ms
Measurement invocations: 1
Measurement avg time:    15960.464 ms (+-NaN)
Benchmark 'Map_Error_Benchmark_Array_ignore.Map_Id_All_Errors' finished in 32313.34 ms
Benchmarking 'Map_Error_Benchmark_Array_report_warning.Map_Id_All_Errors' with configuration: [warmup={3 iterations, 3 seconds each}, measurement={3 iterations, 3 seconds each}]
Warmup duration:    16355 ms
Warmup invocations: 1
Warmup avg time:    16352.555 ms (+-NaN)
Measurement duration:    16418 ms
Measurement invocations: 1
Measurement avg time:    16414.449 ms (+-NaN)
...

We first need to fix the JMH stdlib benchmark invocation.

@Akirathan
Copy link
Member Author

However, the PR that most likely caused the regression is #9625. I cannot verify it at the moment, though.

@JaroslavTulach
Copy link
Member

However, the PR that most likely caused the regression is #9625. I cannot verify it at the moment, though.

Let's make sure @GregoryTravis is aware of that.

@Akirathan
Copy link
Member Author

To me, it seems like #9625 changed the behavior of dataflow errors so that the stack traces are now attached all the time again. They used to be attached only iff JVM assertions were enabled.

@GregoryTravis
Copy link
Contributor

@Akirathan it actually isn't the stack trace that is the problem. As @JaroslavTulach suggested, it is the overhead of calling hasContextEnabled each time in DataflowError.withDefaultTrace. In the affected benchmarks ("Map_Id_All_Errors"), it is called 50M times, because it is testing a 100k array/vector with an error on each element. The other benchmarks are not affected in the same way. So the regression was occurring in an extreme test of this code.

I reproduced the regression locally, and it was not adding stack traces at all.

(Of course Stack traces definitely do add overhead, but these will only be added if the user explicitly requests them using Context.Dataflow_Stack_Trace.with_enabled, which is an advanced feature.)

A possible temporary fix for this would be to again require the "-ea" flag to even check the Execution_Environment settings; we could then create a custom flag for this to use instead of "-ea".

However, we might consider leaving it as-is, since this only affects error paths, and seems to only be noticeable in the case of a large number of errors. (In regular usage, we restrict the errors to 100, I believe.)

@JaroslavTulach
Copy link
Member

it is the overhead of calling hasContextEnabled each time in DataflowError.withDefaultTrace

Speed it up!

@JaroslavTulach
Copy link
Member

Pavel, please take a look and speed the hasContextEnabled check up.

@JaroslavTulach JaroslavTulach changed the title stdlib benchmarks regression 2024-07-29 stdlib benchmarks regression: DataflowError with stack Aug 23, 2024
@Akirathan
Copy link
Member Author

Investigating the regression in PR #11153 on latest develop (03369b9) reveals that the problem is not in ExecutionEnvironment.hasContextEnabled, but in EnsoContext.getExecutionEnvironment. To prove this theory, apply the following patch:

diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java
index 1f44b2329..bbb8d8b1a 100644
--- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java
+++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/EnsoContext.java
@@ -874,8 +874,7 @@ public final class EnsoContext {
   }
 
   public ExecutionEnvironment getExecutionEnvironment() {
-    ExecutionEnvironment env = language.getExecutionEnvironment();
-    return env == null ? getGlobalExecutionEnvironment() : env;
+    return ExecutionEnvironment.LIVE;
   }
 
   /** Set the runtime execution environment of this context. */

and then, the score of Map_Error_Benchmark_Vector_ignore.Map_Id_All_Errors benchmarks goes from 1.2 to 0.132.

TL;DR; The most important part to optimize is EnsoContext.getExecutionEnvironment and not ExecutionContext.hasContextEnabled.

@enso-bot
Copy link

enso-bot bot commented Oct 15, 2024

Pavel Marek reports a new STANDUP for today (2024-10-15):

Progress: - Merging and restarting jobs on #11321 and #11217

@JaroslavTulach
Copy link
Member

TL;DR; The most important part to optimize is EnsoContext.getExecutionEnvironment and not ExecutionContext.hasContextEnabled.

I am not completely sure.

   public ExecutionEnvironment getExecutionEnvironment() {
-    ExecutionEnvironment env = language.getExecutionEnvironment();
-    return env == null ? getGlobalExecutionEnvironment() : env;
+    return ExecutionEnvironment.LIVE;
   }

By returning a compilation constant from getExecutionEnvironment you can eliminate cost of other computations based on this constant (including hasContextEnabled), but the problem is: getExecutionEnvironment cannot be a compilation constant all the time- that was the whole point of #11173

We can speculate with Assumption on the getExecutionEnvironment value to never be changed during execution. It would:

We can go with the Assumption route, but we probably also need to think about optimizing hasContextEnabled.

@enso-bot
Copy link

enso-bot bot commented Oct 17, 2024

Pavel Marek reports a new STANDUP for yesterday (2024-10-16):

Progress: - Managed to improve the perf a little bit.

@enso-bot
Copy link

enso-bot bot commented Oct 17, 2024

Pavel Marek reports a new STANDUP for today (2024-10-17):

Progress: - Context handling functionality converted to nodes.

GitHub
Fixes #10702 Pull Request Description Improves the speed of ExecutionEnvironment.hasContextEnabled. Important Notes Local speedup of Map_Error_Benchmark_Vector_ignore.Map_Id_All_Errors benchmark is...

@mergify mergify bot closed this as completed in #11153 Oct 24, 2024
@github-project-automation github-project-automation bot moved this from 👁️ Code review to 🟢 Accepted in Issues Board Oct 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
--low-performance --regression Important: regression -compiler -libs Libraries: New libraries to be implemented p-high Should be completed in the next sprint
Projects
Status: 🟢 Accepted
Development

Successfully merging a pull request may close this issue.

3 participants