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 App的会员连续扣费
  • ¥15 不同数据类型的特征融合应该怎么做
  • ¥15 用proteus软件设计一个基于8086微处理器的简易温度计
  • ¥15 用联想小新14Pro
  • ¥15 multisim中关于74ls192n和DSWPK开关仿真图分析(减法计数器)
  • ¥15 基于8255的交通灯设计
  • ¥15 w3wp,exe 中发生未处理的 Microsoft ,NETFramework 异常。
  • ¥20 C51单片机程序及仿真(加减器)
  • ¥15 AQWA | 水动力分析 二阶波浪力
  • ¥15 c语言题目:成绩管理系统