在GoLang应用程序中使用C(++)来提高性能 [英] Using C(++) in a GoLang application for performance

查看:1884
本文介绍了在GoLang应用程序中使用C(++)来提高性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开始学习Go几天前,来自它的CGO东西和gccgo编译器。从我的理解,这允许一个Go程序使用Go编译器编译和使用C编译器编译C库,并在Go程序中引用这些库。这对我真的很有趣,因为这允许我们从我们的主程序中利用C的性能(如果需要),而只需很少的开销。



但我不知道是,所以我问这里:



有没有情况下,你会创建一个C库只是为了使用它从你的Go应用程序?或者这个功能只是为了方便现有C代码的重用?



PS:我认为目前CGO不支持C ++,但有一个职位在这里

解决方案

Cgo相当慢,因为Go必须以某些方式混淆其运行时和调用约定调用C函数。唯一真正值得的地方是计算时间显着缩短此费用的情况。它类似于并行,分布式,GPU等编程,虽然稍微降低了启动成本。



组装更好,因为你可以编写使用Go的调用约定,否则就像原生Go代码一样处理,但是组装远远不够便携,难以阅读,而且维护更重。事实上,Go标准库在Plan 9风格的程序集中写了一些 math 大包 p>

Gonum 就是这两个例子。它使用公共组件的一些功能,可以更快地做到这一点,但它也利用blas和lapack引擎。它提供了一个 Go-blas 实现,但是C-blas(通常最终是Fortran-blas)更快,对于大矩阵计算,总是比离开的成本Go。



一般来说,您可以尽可能避免使用cgo。只有在需要大量计算时间时才使用它,需要与在纯Go中进行交互的事物进行交互,如图形或音频驱动程序,或访问OpenCV 。即使如此,如果你真的关心性能,在可能的情况下,可能值得实现某种调用池,您可以从Go侧计划多个调用,并一次执行它们一个上下文切换到C。



编辑:对于C ++,有一些重要的问题。它可能很难包装某些库没有几层抽象(因为cgo不能正确处理包括的C ++头)。此外,带有析构函数的C ++类实际上不能通过值返回,并且必须在堆上分配。由于Go不允许资源的确定性最终化,您必须提供一个函数来显式释放内存,Go用户必须记住释放资源。 (有一个函数,你可以在文档中看到 runtime.SetFinalizer ,但我不能说我见过任何人使用它,而且文档本身一系列警告)



defer 之类的功能使得这更易于管理,但它会破坏许多事情RAII,使现代C ++实践更安全。


I've started studying Go a couple of days ago and came by its CGO thing and the gccgo compiler. From my understanding this allows a Go program to compile using the Go compiler and compile C libraries using a C compiler and reference those libraries from inside a Go program. This is really interesting to me because this allows us to leverage C's performance (if needed) from our main program with little overhead.

However I'm not sure how little that is, so I'm asking here:

Are there cases where you would create a C library just to use it from inside your Go application? Or is this feature only to facilitate re-usability of existing C code?

P.S: I think at the moment CGO doesn't support C++ but there was a post here of someone that was able to wrap C++ code using C functions and call them successfully.

解决方案

Cgo is fairly slow, because Go has to mess with its runtime and calling conventions in certain ways to call C functions. The only place it's really worth it is cases where the compute time significantly dwarfs this cost. It's similar to parallel, distributed, GPU and so on programming, albeit with slightly lower startup costs.

Assembly is much better, because you can write assembly that uses Go's calling convention, and is otherwise treated like native Go code, but assembly is far less portable, harder to read, and more maintenance heavy. In fact, the Go standard library writes some of the math and big packages in Plan 9-style assembly.

Gonum is an example of both of these. It uses common assembly for some functions that can be done more quickly that way, but it also leverages blas and lapack engines. It does provide a Go-blas implementation, but C-blas (which is usually ultimately Fortran-blas) is faster, and for large matrix computations almost always dwarfs the cost of leaving Go.

Generally, you want to avoid cgo when possible. Only use it when significant computation time is needed, or you need to interact with things that would be non-trivial to interact with in pure Go, such as graphics or audio drivers, or accessing common libraries like OpenCV. Even then, if you really care about performance, where possible it may be worth it to implement some sort of "call pooling" where you can schedule multiple calls from the Go side and execute them all at once with a single context switch to C.

Edit: As for C++, there are some significant issues. It can be difficult to wrap certain libraries without several layers of abstraction (since cgo cannot handle included C++ headers properly). In addition, C++ classes with destructors can't really be returned by value and have to be allocated on the heap. Since Go doesn't allow for deterministic finalization of resources, you must provide a function to explicitly free memory, and the Go user must remember to free the resource. (There is a function you may read about in the documentation called runtime.SetFinalizer but I can't say I've ever seen anyone use it, and the documentation itself comes with a bunch of caveats)

Functionality such as defer makes this more manageable, but it ruins a lot of things like RAII which make modern C++ practices safer.

这篇关于在GoLang应用程序中使用C(++)来提高性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆