In a project I'm working on I need to use a bunch of C functions from Go. The current implementation is using cgo to achieve that, but doing so has a massive performance impact, which I am trying to remove.
GOMAXPROCS
(= 8)), which my Linux kernel does not like much.I want to keep using Go for this project as it's a great way of managing concurrency.
Things I have tried :
entersyscall()
in src/runtime/cgocall.go
(didn't seem to help much, and I'd prefer to avoid modifying the Go code).import "C"
. No luck here - I couldn't call the function and when I wrote the function names as package·function
the compiler complained about invalid characters in the file.So, my question is: how does one use C functions from Go while avoiding the overhead of cgo?
Side note: I'm aware of why cgo marks all calls as a syscall, but in this specific case the functions I call do not block on locks or IO.
What you want to do is not possible. There is a reason that C code has a high overhead, which is that C code uses a different ABI (the platform's native ABI) which doesn't support the short stacks Go uses. Thus whenever Go code calls C code, execution has to continue on the threads native stack. This causes the overhead you see. There is no† way to remove this overhead. Think about it: If the overhead wasn't needed, it wouldn't exist.
It's hard to say what you should do instead without knowing what your program looks like.
†You could compile your C code with the C compiler from the Go project, but that compiler doesn't optimize nearly as well as gcc or clang do and your code will definitely break in a future version of Go as that compiler is not part of any stable interface.