-
-
Notifications
You must be signed in to change notification settings - Fork 251
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
perf: Remove all Cgo handles #1073
Conversation
@withinboredom I also noticed that with the current settings of Changing this to |
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.
Awesome! Very good idea.
frankenphp.go
Outdated
@@ -517,25 +502,25 @@ func ServeHTTP(responseWriter http.ResponseWriter, request *http.Request) error | |||
} | |||
|
|||
//export go_handle_request | |||
func go_handle_request() bool { | |||
func go_handle_request(threadIndex int) bool { |
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.
Shouldn't we use uint64_t
or uint32_t
everywhere? (C-side and Go side)? The current implementation may trigger incompatibilities between C and Go types if a (very) large number of threads is started.
func go_handle_request(threadIndex int) bool { | |
func go_handle_request(threadIndex C.uint64_t) bool { |
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 was wondering how go treats the integers coming from C since they don't seem to need casting. I changed it to uint32_t
since I'm not sure how uint64_t
would be cast on 32 bit systems.
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.
After thinking about this a bit more, maybe the best option is C.uintptr_t
. As Go's int
type, it will have a different size depending on the platform capabilities, and it will prevent a conversion C-side.
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.
Should it then be a map of C.uintptr_t
? A slice still works, but it somehow feels weird to do this: phpThreads[C.uintptr_t(i)]
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.
it shouldn't be an issue
By the way, I would like to contact you privately @AlliBalliBaba, I couldn't find a way to contact you, would you mind sending a mail or a DM on any social network? |
bfd3534
to
756675f
Compare
@AlliBalliBaba I simplified the code, rebased and renamed a function to match our CS in |
Sounds good to me 👍 |
Thank you @AlliBalliBaba!! |
@dunglas fyi I sent you mail on [email protected] |
This PR aims to improve handle performance as discussed in #934
Instead of optimizing handles, they are completely removed and replaced by passing the index of the current thread
This makes it so we can store a slice of
phpThreads
on the go side and have more potential control over threadcreation/destruction/metrics.
The performance impacts are similar to #934.
A quick worker benchmark:
wrk -t 4 -c 150 -d 60
on WSL bookworm-Docker 20 CPU cores 40 threadswithout this PR: ~57000 req/s
with this PR: ~65000 req/s
Note that this benchmark was done with php_import_environment_variables disabled (I plan to optimize that it in a separate PR).
This PR comes with some significant refactoring (especially in
worker.go
) so I hope it doesn't conflict too much with other potential PRs.