文档章节

如何把Go调用C的性能提升10倍?

LinkerLin
 LinkerLin
发布于 2017/09/06 14:48
字数 564
阅读 4973
收藏 79

目前,当Go需要和C/C++代码集成的时候,大家最先想到的肯定是CGO。毕竟是官方的解决方案,而且简单。

但是CGO是非常慢的。因为CGO其实一个桥接器,通过自动生成代码,CGO在保留了C/C++运行时的情况下,搭建了一个桥来沟通C/C++世界和Go的世界。这就意味着,兼容性很好,但是对C的函数的调用,必须先把当前的goroutine挂起,并切换执行栈到当前的线程M的主栈(大小2MB)。如果不做这个操作,那么只能在goroutine的栈上执行C函数调用,可是,goroutine的栈一般都很小,很容易就导致了栈溢出了。

调用C函数的时候,必须切换当前的栈为线程的主栈,这带来了两个比较严重的问题:

  1. 线程的栈在Go运行时是比较少的,受到P/M数量的限制,一般可以简单的理解成受到GOMAXPROCS限制;
  2. 由于需要同时保留C/C++的运行时,CGO需要在两个运行时和两个ABI(抽象二进制接口)之间做翻译和协调。这就带来了很大的开销。

minio项目的一个副产品是 c2goasm 项目,这个项目也被 go-cv-simd 项目使用获得了很好的效果。

c2goasm 的角色是一个 汇编语言转换器,输入是 clang输出的amd64汇编,输出是go汇编。而clang的输入是C/C++语言。限制是不能有RTTI和异常。也就是说不能有C/C++运行时提供的高级功能。

c2goasm输出的go汇编,交给go的工具链可以直接生成go的可执行代码。

c2goasm和CGO比,最大的改进就是:

  1. 不再有C/C++运行时,也就没了在两者之间不停转换的逻辑开销;
  2. 不需要切换到线程的主栈来执行函数,因为c2goasm生成的是纯正的go函数,不需要线程的主栈就可以执行;

由此就极大的改进了性能,代价是兼容性和可移植性损失了。

© 著作权归作者所有

共有 人打赏支持
LinkerLin

LinkerLin

粉丝 71
博文 63
码字总数 14069
作品 1
长宁
程序员
私信 提问
加载中

评论(25)

LinkerLin
LinkerLin

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

我就喜欢看一本正经的胡说八道。c/c++都没有运行时。

回复@nullref : C/C++ 都有运行时的,C的运行时很简单但也不能忽略。说C++没有运行时那就是没看过Clang源码啦。
兄台说的可是运行时库?别强要面子了,兄台连运行时的概念都没有!
解释型,半静态语言才能称有运行时。例如C#/java/js/py/lua等

回复@nullref : C/C++当然有runtime了,你可以去看下clang的源码。

引用来自“nullref”的评论

我做这块工作六年了,有没有运行时,我很清楚。你拿一个library来说这语言有run time,是搞笑艺人么?
运行时 这个东西的概念,不等于脚本语言用的VM。
LinkerLin
LinkerLin

引用来自“nullref”的评论

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

我就喜欢看一本正经的胡说八道。c/c++都没有运行时。

回复@nullref : C/C++ 都有运行时的,C的运行时很简单但也不能忽略。说C++没有运行时那就是没看过Clang源码啦。
兄台说的可是运行时库?别强要面子了,兄台连运行时的概念都没有!
解释型,半静态语言才能称有运行时。例如C#/java/js/py/lua等

回复@nullref : C/C++当然有runtime了,你可以去看下clang的源码。
我做这块工作六年了,有没有运行时,我很清楚。你拿一个library来说这语言有run time,是搞笑艺人么?

回复@nullref : 你看下clang、gcc的源码啊。C有自己的crt C run time library.
nullref
nullref

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

我就喜欢看一本正经的胡说八道。c/c++都没有运行时。

回复@nullref : C/C++ 都有运行时的,C的运行时很简单但也不能忽略。说C++没有运行时那就是没看过Clang源码啦。
兄台说的可是运行时库?别强要面子了,兄台连运行时的概念都没有!
解释型,半静态语言才能称有运行时。例如C#/java/js/py/lua等

回复@nullref : C/C++当然有runtime了,你可以去看下clang的源码。
我做这块工作六年了,有没有运行时,我很清楚。你拿一个library来说这语言有run time,是搞笑艺人么?
LinkerLin
LinkerLin

引用来自“nullref”的评论

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

我就喜欢看一本正经的胡说八道。c/c++都没有运行时。

回复@nullref : C/C++ 都有运行时的,C的运行时很简单但也不能忽略。说C++没有运行时那就是没看过Clang源码啦。
兄台说的可是运行时库?别强要面子了,兄台连运行时的概念都没有!
解释型,半静态语言才能称有运行时。例如C#/java/js/py/lua等

ObjC/Swift/C/C++都有运行时的。
LinkerLin
LinkerLin

引用来自“nullref”的评论

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

我就喜欢看一本正经的胡说八道。c/c++都没有运行时。

回复@nullref : C/C++ 都有运行时的,C的运行时很简单但也不能忽略。说C++没有运行时那就是没看过Clang源码啦。
兄台说的可是运行时库?别强要面子了,兄台连运行时的概念都没有!
解释型,半静态语言才能称有运行时。例如C#/java/js/py/lua等

回复@nullref : http://blog.csdn.net/luoweifu/article/details/49049877
LinkerLin
LinkerLin

引用来自“nullref”的评论

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

我就喜欢看一本正经的胡说八道。c/c++都没有运行时。

回复@nullref : C/C++ 都有运行时的,C的运行时很简单但也不能忽略。说C++没有运行时那就是没看过Clang源码啦。
兄台说的可是运行时库?别强要面子了,兄台连运行时的概念都没有!
解释型,半静态语言才能称有运行时。例如C#/java/js/py/lua等

回复@nullref : C/C++当然有runtime了,你可以去看下clang的源码。
nullref
nullref

引用来自“LinkerLin”的评论

引用来自“nullref”的评论

我就喜欢看一本正经的胡说八道。c/c++都没有运行时。

回复@nullref : C/C++ 都有运行时的,C的运行时很简单但也不能忽略。说C++没有运行时那就是没看过Clang源码啦。
兄台说的可是运行时库?别强要面子了,兄台连运行时的概念都没有!
解释型,半静态语言才能称有运行时。例如C#/java/js/py/lua等
LinkerLin
LinkerLin

引用来自“nullref”的评论

我就喜欢看一本正经的胡说八道。c/c++都没有运行时。

回复@nullref : C/C++ 都有运行时的,C的运行时很简单但也不能忽略。说C++没有运行时那就是没看过Clang源码啦。
不会飞的猪
不会飞的猪
很厉害~ mark
nullref
nullref
我就喜欢看一本正经的胡说八道。c/c++都没有运行时。
zlog 1.0.6 发布,纯C日志函数库

再次感谢[nikuailema at gmail.com],找到了zlog的另一个瓶颈。 在我的开发环境下 -------------------------------------------------v1.0.6$ time ./testpresszlog 1 10 100000real 0m1.81......

难易
2012/06/15
456
3
MongoDB 3.0性能提升内幕:WiredTiger

  【IT168 评论】MongoDB出现是个意外,最初的想法是构建一个用于开发、托管并具有自动缩放Web应用程序的在线服务,而不是数据库。结果无心插柳柳成荫,却成就了全球最流行的NoSQL数据库,...

it168网站
2015/04/18
0
0
利用 psyco 让 Python 程序执行更快

Python 和其他的脚本语言在性能上跟一些编译语言(如C语言)比较要差不少,例如这里有两个用 C 和 Python 语言编写的斐波纳契数列计算程序: C语言: int fib(int n){if (n < 2) else } int...

红薯
2013/01/08
14.8K
48
Cython 三分钟入门

作者:perrygeo 译者:赖勇浩(http://laiyonghao.com) 原文:http://www.perrygeo.net/wordpress/?p=116 我最喜欢的是Python,它的代码优雅而实用,可惜纯粹从速度上来看它比大多数语言都要...

鉴客
2012/02/23
6.5K
4
吞吐量(Throughput)、QPS、并发数、响应时间(RT)

吞吐量:系统在单位时间内处理请求的数量,是并发系统的一个重要的性能指标。 QPS(每秒查询率 Query Per Second):对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网...

Jack_Q
2015/04/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Redis分布式锁的实现原理看这篇就够了~

一、写在前面 现在面试,一般都会聊聊分布式系统这块的东西。通常面试官都会从服务框架(Spring Cloud、Dubbo)聊起,一路聊到分布式事务、分布式锁、ZooKeeper等知识。 所以咱们这篇文章就来...

Java干货分享
7分钟前
0
0
Actor并发编程模型浅析

一.Actor模型介绍 在单核 CPU 发展已经达到一个瓶颈的今天,要增加硬件的速度更多的是增加 CPU 核的数目。而针对这种情况,要使我们的程序运行效率提高,那么也应该从并发方面入手。传统的多...

终日而思一
8分钟前
0
0
利用arthas实时定位线上性能问题

0. 场景及需求 我们线上5台solr读服务器,配置一样,但是相同的请求,其中一台响应时间明显比其他4台慢,我们想通过arthas来定位具体哪里执行慢。 1. arthas介绍 阿里开源的java调试工具,能...

andersChow
9分钟前
1
0
docker 启动策略

Docker run的时候使用--restart参数 no - Container不重启 on-failure - container推出状态非0时重启 always - 始终重启 例如: docker run --restart=always -itd -p 2222:22 -p 3306:3306......

colin_86
9分钟前
0
0
Thinkphp5开发OA办公系统之招聘申请

开发运行环境: 神舟笔记本K650D-G6D1 i5-6400 GTX950M Windows 10 专业版 Nginx 或 Apache Web 服务器软件 MySQL5.7.x 数据库 PHP7.1.0 PHPStrom 2017 PowerDesigner 16.5 Axure RP8 原型设......

乐兔CRM
12分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部