-
Notifications
You must be signed in to change notification settings - Fork 25
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
feature/mulithreading-changes #168
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #168 +/- ##
==========================================
+ Coverage 97.49% 99.20% +1.71%
==========================================
Files 20 19 -1
Lines 1157 1138 -19
==========================================
+ Hits 1128 1129 +1
+ Misses 29 9 -20 ☔ View full report in Codecov by Sentry. |
Hi @JanisErdmanis, I have tested both approaches locally on my laptop with Julia 1.6 and 1.10 and found either the same or better performance with these changes. The results of this test almost feel too good to be true which makes me a bit hesitant. What do you think? |
Hi @ndortega Sorry, I did not see the message. I am unfamiliar with the parallelism internals and don't yet use them; thus, I can't comment on the performance. But I am happy that there is such a feature and may find it helpful in the future. For now, I can only offer some ideas to consider:
I am rather busy and can't help with coding. EDIT: I think I am able to grasp how parallelism is implemented now. I find it concerning that there is a shared mutable state between threads, which is introduced by the metrics history object. A simple fix would be to create a history object for each thread and then aggregate that in a single history object, which can be shown on the metrics page. But perhaps that is unnecessary for |
Hi @JanisErdmanis, I'm glad you brought up that point about the shared History object. I've used a And I agree with your second point, with these latest changes the functions are basically identical to one another and could be merged into a single one |
You could look into implementing a function An alternative to using |
I liked the idea of dropping the Now that the main thread was used for docs & metrics middleware exclusively - I had to make the metrics endpoint was asynchronous in order to prevent the app from halting when viewing the metrics under heavy load. Even after these changes I was surprised to see a 2x slowdown in RPS on my laptop between this approach and the If you're curious and want to view this code let me know and I'll push that branch |
This is unexpected. I wonder if it could be due to tasks also being scheduled on the main thread which could slow it down. Push the code on the branch, I may have a look. |
Sure thing, here's the branch I was working out of: https://github.com/OxygenFramework/Oxygen.jl/tree/feature/multi-threading-experimental-changes |
Yeah. You may find interesting to explore ThreadPools.jl. EDIT: The issue is that the metrics middleware waits for the response |
Exactly, it won't be worth making this refactor until I speed up the metrics calculations. This shouldn't be too difficult since the helper utils are all very similar. Out of the 7 metrics returned:
Possible Next Steps:
|
Perhaps you can also consider of using a channel where requests are being but by the main thread and then processed by each individual thread returning I think the design decission here needs to be supported by benchmarks. One of the ways is to check how many requests per second it takes to satturate HTTP without metrics and with metrics. If the saturation with metrics is sufficient then it can be shared by every thread and used together with a lock as it is now. Else that needs to be put within each system thread event loop to improve throughput. |
found a 10 - 15% performance gain by removing the current queue + multithreading approach and leaning harder on the scheduler built into Julia using a cooperative multitasking strategy.
Additionally, the amount of code to get this working allowed me to completely remove the StreamUtil module, some state variables, and type definitions in favor of a single function - which makes it much easier to maintain.