c++ - 在 Go 应用程序中使用 C(++) 提高性能

标签 c++ c go gccgo

几天前我开始学习 Go 并了解了它的 CGO 和 gccgo 编译器。根据我的理解,这允许 Go 程序使用 Go 编译器进行编译,并使用 C 编译器编译 C 库,并从 Go 程序内部引用这些库。这对我来说真的很有趣,因为这使我们能够以很少的开销从我们的主程序中利用 C 的性能(如果需要)。

但是我不确定那有多少,所以我在这里问:

在某些情况下,您会创建一个 C 库只是为了在您的 Go 应用程序中使用它吗?或者此功能只是为了促进现有 C 代码的可重用性?

P.S:我认为目前 CGO 不支持 C++,但这里有一篇帖子有人能够使用 C 函数包装 C++ 代码并成功调用它们。

最佳答案

Cgo 相当慢,因为 Go 必须 mess with its runtime and calling conventions以某些方式调用 C 函数。唯一真正值得的地方是计算时间明显相形见绌的情况 this cost .它类似于并行、分布式、GPU 等编程,尽管启动成本略低。

汇编要好得多,因为您可以编写使用 Go 调用约定的汇编,并且在其他方​​面被视为本地 Go 代码,但汇编的可移植性差得多,更难阅读,而且维护工作量更大。事实上,Go 标准库在 Plan 9 风格的汇编中编写了一些 mathbig 包。

Gonum是这两者的一个例子。它对一些可以更快完成的功能使用通用汇编,但它也利用了 blas 和 lapack 引擎。它确实提供了一个 Go-blas 实现,但 C-blas(通常最终是 Fortran-blas)更快,而且对于大型矩阵计算,几乎总是比离开 Go 的成本相形见绌。

通常,您希望尽可能避免 cgo。仅在需要大量计算时间时才使用它,您需要与在纯 Go 中交互非常重要的事物进行交互,例如图形或音频驱动程序,或访问 OpenCV 等公共(public)库.即便如此,如果你真的关心性能,在可能的情况下实现某种“调用池”可能是值得的,你可以从 Go 端安排多个调用并通过单个上下文切换到 C 一次执行它们。

编辑:至于 C++,有一些重要的问题。如果没有多层抽象,可能很难包装某些库(因为 cgo 无法正确处理包含的 C++ header )。此外,具有析构函数的 C++ 类不能真正按值返回,必须在堆上分配。由于 Go 不允许资源的确定性终结,因此您必须提供显式释放内存的函数,并且 Go 用户必须记住释放资源。 (您可能会在名为 runtime.SetFinalizer 的文档中读到一个函数,但我不能说我见过任何人使用过它,而且文档本身也有很多注意事项)

defer 等功能使这更易于管理,但它破坏了很多东西,例如 RAII,使现代 C++ 实践更安全。

关于c++ - 在 Go 应用程序中使用 C(++) 提高性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37960425/

相关文章:

c - 段错误(核心转储)错误

c - 为什么当我第二次运行循环时该程序会崩溃?

在 Go 中排序和比较数组

c++ - 加入 Portaudio 和 Opus

c++ - 在 C++ 中创建一个键值对字典

c++ - TBB 并发 vector 是否支持旧的 C 风格循环?

c++ - 类定义中的 bad_alloc 错误

c - 在代码非常直接的部分发生段错误

go - 是否可以在运行时删除结构值的字段?

postgresql - 更新模型对象时,如何将整数列设置为null?