dongtiao2105 2015-01-24 16:56
浏览 174

如何不使用cgo将Go函数绑定到C调用?

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.

  • cgo marks all C code as a syscall, causing the scheduler to allocate a new thread if needed. Since ~80% of the CPU time in my project is spent doing the heavy C work, this quickly results in having a lot of threads (500+ instead of GOMAXPROCS (= 8)), which my Linux kernel does not like much.
  • Doing the usual 'limiter' approach (have a buffered channel lock the cgo calls) results in a lot of mutexes, slowing the program down.

I want to keep using Go for this project as it's a great way of managing concurrency.

Things I have tried :

  • Comment out some stuff like entersyscall() in src/runtime/cgocall.go (didn't seem to help much, and I'd prefer to avoid modifying the Go code).
  • Put my code in a .c file and call it from Go, without the 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.
  • Use a .s file and just write it as assembly. My asm isn't that great and I couldn't figure it out.

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.

  • 写回答

1条回答 默认 最新

  • dongyin2390 2015-01-24 17:13
    关注

    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.

    评论

报告相同问题?

悬赏问题

  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 shape_predictor_68_face_landmarks.dat
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料