-
Notifications
You must be signed in to change notification settings - Fork 43
Implement multi-threading in NativeRunner #91
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
Implement multi-threading in NativeRunner #91
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements multi-threading support in the NativeRunner to enable parallel ray tracing. The implementation introduces a ThreadManager class to coordinate multiple worker threads, refactors the TRayData structure to handle thread-safe ray data collection, and updates the trace functions to support concurrent execution.
Key changes include:
- Addition of ThreadManager class for thread coordination and monitoring
- Refactoring of ray tracing to split work across multiple threads with unique seeds
- Conversion of ray numbering from unsigned int to uint_fast64_t to support larger simulations
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| thread_manager.hpp/cpp | New ThreadManager class for managing multiple worker threads, tracking progress, and handling cancellation |
| trace.hpp/cpp | Refactored trace_native to spawn multiple threads and added trace_single_thread for per-thread execution |
| native_runner.hpp/cpp | Added thread count and seed management, delegated status/cancel operations to ThreadManager |
| native_runner_types.hpp/cpp | Completely refactored TRayData from block-based storage to thread-indexed map structure for concurrent access |
| pt_optimizations.hpp/cpp | Changed rec_hash parameter from reference to pointer for thread sharing |
| process_interaction.cpp | Removed commented-out myrng_counter increments |
| generate_ray.hpp/cpp | Made PosSunStage parameter const for thread safety |
| simulation_runner.hpp | Added UNKNOWN status and status_string utility function |
| native_runner_test.cpp | Changed EXPECT_EQ to ASSERT_EQ in critical assertions, added tests for multi-threaded cancellation and ray ID assignment |
| native_runner_multithreading_test.cpp | New regression test for multi-threaded performance validation |
| count_absorbed_native.cpp | Updated ray variable type from unsigned int to uint_fast64_t |
| simulation_data.hpp | Enhanced comment documentation for clear() method |
| mtrand.hpp | Code formatting improvements (whitespace and brace placement) |
| CMakeLists.txt | Added thread_manager.cpp to build and new multithreading test file |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
coretrace/simulation_runner/native_runner/native_runner_types.cpp
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 24 out of 24 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
google-tests/regression-tests/native_runner_multithreading_performance_test.cpp
Show resolved
Hide resolved
…ancel multithread test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I merged this into my validation branch and see no performance change when switching to multi-threading. Maybe we should discuss when you get a chance.
| // // TODO: This should throw an error... | ||
| // // Get RaySource data (this runner assumes there is only the Sun) | ||
| // assert(data->get_number_of_ray_sources() == 1); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove
| if (data->get_number_of_elements() <= 0) | ||
| { | ||
| throw std::invalid_argument("SimulationData has no elements."); | ||
| // return RunnerStatus::ERROR; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove
| ThreadInfo my_info; | ||
| my_info.manager = manager; | ||
| my_info.System = System; | ||
| my_info.NumberOfRays = NumberOfRays / nthreads; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method does not preserve the expected ray count. Can we set unique number of rays by thread? This would allow each thread to run the truncated value of <NumberOfRays / nthreads> and one thread with the added remainder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
| TSystem *System, | ||
| unsigned int seed, | ||
| uint_fast64_t NumberOfRays, | ||
| uint_fast64_t MaxNumberOfRays, // TODO: How to handle MaxRays? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can handle the Max number of rays the same way as the number of rays. Each thread assigned with the truncated value of MaxNumberOfRays / nthreads, then one thread gets the remainder. This should preserve the user input of MaxNumberOfRays.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
|
||
| TEST(NativeRunner, Multithreading) | ||
| { | ||
| const uint_fast64_t NRAYS = 50000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a check that confirms NRAYS in preserved in results?
| runner.print_log(std::cout); | ||
| } | ||
|
|
||
| ASSERT_EQ(nrec, NRAYS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works because 50,000 is divisible by 4.
| std::cout << "Num Elements: " << sd.get_number_of_elements() << std::endl; | ||
|
|
||
| // Parameters | ||
| SimulationParameters ¶ms = sd.get_simulation_parameters(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why should not put number of threads in the simulation parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Number of threads is really a property of the ray tracer and not the ray tracing problem. It logically doesn't belong in the simulation parameters.
I tested this by merging it into the legacy GUI branch, and adding threads did not speed up the simulation in my case either. |
Taylor, I resolved this issue on my end yesterday. The reason I didn't see a speed increase was because the number of rays I was running was too small and the ray data process method after the trace was the bigger bottleneck. Just an FYI. |
qualand
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for updating the method to maintain desired ray count!
My issue is related to running in debug from the GUI. I ran the same stinput case via testing in release and saw speed improvement with added threads. |
|
Any objections to merging? |
No description provided.