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 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵