-
-
Notifications
You must be signed in to change notification settings - Fork 4
Benchmark simplify operation #250
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
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
c2199d6
Add bench_simplify.jl
ufechner7 a274ed8
bench_simplify works
ufechner7 000395d
Add comment
ufechner7 8691bdb
Update comments
ufechner7 de77efb
Update benchmark
ufechner7 afd22f2
Minor changes
ufechner7 d61b067
Make sure sam.sys is defined
ufechner7 303a96d
Calc rel performance
ufechner7 5ca6527
Add file to .gitignore
ufechner7 1ecda68
Run in separate process
ufechner7 66e92e5
Update comment
ufechner7 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| # SPDX-FileCopyrightText: 2022 Uwe Fechner | ||
| # SPDX-License-Identifier: MIT | ||
|
|
||
| const reference = 4.826620521958565e7 # AMD Ryzen 7840U, Julia 1.11, 1 thread | ||
|
|
||
| """ | ||
| cpu_benchmark_scalar(target_time=1.0) | ||
|
|
||
| Performs scalar CPU-intensive operations without SIMD for approximately `target_time` seconds. | ||
| This function performs basic arithmetic operations on scalar values to measure CPU performance | ||
| without utilizing vector/SIMD instructions. | ||
|
|
||
| Returns the number of operations performed and the actual elapsed time. | ||
| """ | ||
| function cpu_benchmark_scalar(target_time=1.0) | ||
| # First, do a short calibration run to estimate operations per second | ||
| calibrate_ops = 1_000_000 | ||
| start_cal = Base.time() | ||
|
|
||
| # Scalar operations that avoid SIMD optimization | ||
| result = 0.0 | ||
| x = 1.23456789 | ||
| y = 9.87654321 | ||
|
|
||
| for i in 1:calibrate_ops | ||
| # Mix of operations to avoid compiler optimizations | ||
| x = x * 1.000001 + sin(y * 0.001) | ||
| y = y * 0.999999 + cos(x * 0.001) | ||
| result += sqrt(abs(x + y)) | ||
| end | ||
|
|
||
| cal_time = Base.time() - start_cal | ||
| ops_per_second = calibrate_ops / cal_time | ||
|
|
||
| # Estimate total operations needed for target time | ||
| target_ops = Int(round(ops_per_second * target_time)) | ||
|
|
||
| # Main benchmark run | ||
| start_time = Base.time() | ||
| result = 0.0 | ||
| x = 1.23456789 | ||
| y = 9.87654321 | ||
|
|
||
| @inbounds for i in 1:target_ops | ||
| # Scalar arithmetic operations that are hard to vectorize | ||
| x = x * 1.000001 + sin(y * 0.001) | ||
| y = y * 0.999999 + cos(x * 0.001) | ||
| result += sqrt(abs(x + y)) | ||
|
|
||
| # Additional scalar operations to increase workload | ||
| if i % 1000 == 0 | ||
| x = x / (1.0 + 1e-10) # Prevent overflow | ||
| y = y / (1.0 + 1e-10) | ||
| end | ||
| end | ||
|
|
||
| elapsed_time = Base.time() - start_time | ||
|
|
||
| # Force the compiler to use the result (prevent dead code elimination) | ||
| println("Benchmark result (ignore): $(result)") | ||
|
|
||
| return target_ops / elapsed_time | ||
| end | ||
|
|
||
| """ | ||
| rel_cpu_performance() | ||
|
|
||
| A simple CPU benchmark that performs scalar operations for approximately 1 second. | ||
| This is a standalone function that doesn't depend on any external packages. | ||
| """ | ||
| function rel_cpu_performance() | ||
| ops = cpu_benchmark_scalar(1.0) | ||
| println("CPU Performance: $(round(ops/1e6, digits=1)) million operations per second") | ||
| return ops/reference | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| # Copyright (c) 2024, 2025 Bart van de Lint, Uwe Fechner | ||
| # SPDX-License-Identifier: MIT | ||
|
|
||
| SIMPLE = false | ||
| T_REF = 48.0 # AMD Ryzen 7840U, Julia 1.11, no sys image [s] | ||
| # 37s with sys image | ||
|
|
||
| using Pkg | ||
| if ! ("Test" ∈ keys(Pkg.project().dependencies)) | ||
| using TestEnv; TestEnv.activate() | ||
| end | ||
| using KiteModels, LinearAlgebra, Statistics, Test, Distributed | ||
| include("bench_ref.jl") | ||
|
|
||
| # Simulation parameters | ||
| dt = 0.05 | ||
| total_time = 10.0 # Longer simulation to see oscillations | ||
| vsm_interval = 3 | ||
| steps = Int(round(total_time / dt)) | ||
|
|
||
| # Steering parameters | ||
| steering_freq = 1/2 # Hz - full left-right cycle frequency | ||
| steering_magnitude = 10.0 # Magnitude of steering input [Nm] | ||
|
|
||
| # Function to run benchmark in separate Julia process | ||
| function run_benchmark_subprocess() | ||
| # Create a temporary script file for the benchmark | ||
| benchmark_script = """ | ||
| using Pkg | ||
| if ! ("Test" ∈ keys(Pkg.project().dependencies)) | ||
| using TestEnv; TestEnv.activate() | ||
| end | ||
| using KiteModels, LinearAlgebra, Statistics | ||
| include("test/bench_ref.jl") | ||
|
|
||
| SIMPLE = $SIMPLE | ||
| T_REF = $T_REF | ||
|
|
||
| # Initialize model | ||
| set = load_settings("system_ram.yaml") | ||
| set.segments = 3 | ||
| set_values = [-50, 0.0, 0.0] # Set values of the torques of the three winches. [Nm] | ||
| set.quasi_static = false | ||
| set.physical_model = SIMPLE ? "simple_ram" : "ram" | ||
|
|
||
| sam = SymbolicAWEModel(set) | ||
| sam.set.abs_tol = 1e-2 | ||
| sam.set.rel_tol = 1e-2 | ||
| rm("data/model_1.11_ram_dynamic_3_seg.bin"; force=true) | ||
|
|
||
| # Initialize at elevation | ||
| set.l_tethers[2] += 0.2 | ||
| set.l_tethers[3] += 0.2 | ||
| time_ = init!(sam; remake=false, reload=true, bench=true) | ||
| @info "Simplify took \$time_ seconds" | ||
| rel_performance = (T_REF / rel_cpu_performance())/time_ | ||
|
|
||
| # Write results to file for parent process to read | ||
| open("benchmark_results.tmp", "w") do f | ||
| println(f, time_) | ||
| println(f, rel_performance) | ||
| end | ||
| """ | ||
|
|
||
| # Write the script to a temporary file | ||
| temp_script = "temp_benchmark.jl" | ||
| open(temp_script, "w") do f | ||
| write(f, benchmark_script) | ||
| end | ||
|
|
||
| try | ||
| # Run the benchmark in a separate Julia process | ||
| result = run(`julia --project=. $temp_script`) | ||
|
|
||
| if result.exitcode == 0 | ||
| # Read results from temporary file | ||
| if isfile("benchmark_results.tmp") | ||
| lines = readlines("benchmark_results.tmp") | ||
| time_ = parse(Float64, lines[1]) | ||
| rel_performance = parse(Float64, lines[2]) | ||
|
|
||
| @info "Simplify took $time_ seconds" | ||
| @info "Relative performance: $rel_performance" | ||
| @test rel_performance > 0.8 | ||
|
|
||
| # Clean up temporary files | ||
| rm("benchmark_results.tmp", force=true) | ||
| rm(temp_script, force=true) | ||
|
|
||
| return time_, rel_performance | ||
| else | ||
| error("Benchmark results file not found") | ||
| end | ||
| else | ||
| error("Benchmark process failed with exit code $(result.exitcode)") | ||
| end | ||
| catch e | ||
| # Clean up temporary files in case of error | ||
| rm("benchmark_results.tmp", force=true) | ||
| rm(temp_script, force=true) | ||
| rethrow(e) | ||
| end | ||
| end | ||
|
|
||
| # Run the benchmark in a separate process | ||
| time_, rel_performance = run_benchmark_subprocess() | ||
|
|
||
| # Note: sys object is not available when running in separate process | ||
| # If you need sys, you would need to serialize it or run parts in the main process | ||
| nothing | ||
|
|
||
| # Desktop, AMD Ryzen 9 7950X, Julia 1.11: | ||
| # - first run 34.5 seconds | ||
| # - second run 21.1 seconds | ||
|
|
||
| # Laptop, AMD Ryzen 7 7840U, Julia 1.11: | ||
| # - first run 35.0 seconds | ||
| # - second run 24.0 seconds | ||
|
|
||
|
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.