文档章节

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

LinkerLin
 LinkerLin
发布于 2017/09/06 14:48
字数 564
阅读 4743
收藏 79
点赞 4
评论 25

目前,当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

粉丝 70
博文 60
码字总数 13570
作品 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++都没有运行时。
MongoDB 3.0性能提升内幕:WiredTiger

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

it168网站
2015/04/18
0
0
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
利用 psyco 让 Python 程序执行更快

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

红薯
2013/01/08
14.8K
48
微软称 Live Hotmail 速度提升了10倍

Hotmail的产品经理Dick Craddock今天在微软Windows团队博客上发表了一篇文章叙述了Hotmail是如何提升性能的,在上一次更新后,Hotmail的用户体验得到了极大的提升,特别是在速度上实测有10倍...

小编辑
2011/07/01
1K
11
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
使用 Apache Spark 让 MySQL 查询速度提升 10 倍以上

在这篇文章中我们将讨论如何利用 Apache Spark 来提升 MySQL 的查询性能。 在已有的 MySQL 服务器之上使用 Apache Spark (无需将数据导出到 Spark 或者 Hadoop 平台上),这样至少可以提升 ...

绿悠悠
2016/08/28
2.5K
0
使用快速创建索引提高ALTER TABLE的性能

今天我一直在寻找在不同的缓冲池大小的情况下使用快速创建索引和不使用快速创建索引时ALTER TABLE的性能差异。结果很有意思,我使用修改过的Sysbench 表做这些测试,因为原来的表在K这一列已...

王振威
2012/07/29
644
0
让 grep 快 50 倍!

在 Brendan Gregg 的 Blazing Performance with Flame Graphs 演讲中得知: 切换到 LANG=C 可提升 2000 倍的性能 进行快速测试后,我发现没有 2000 倍那么多,我的测试提升了 50 倍的性能。而...

红薯
2013/12/16
1K
6
swoole-1.7.7 发布,Http 服务器性能大幅提升

swoole-1.7.7 发布,内置Http服务器性能是Node.js的12倍 PHP的异步并发扩展swoole发布了 1.7.7 版本,此版本主要有: 增加对cygwin环境的支持 增加单次定时器的after接口 onClose事件调整为在...

matyhtf
2014/10/28
8.7K
65

没有更多内容

加载失败,请刷新页面

加载更多

下一页

利用 acme.sh 获取网站证书并配置https访问

acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书.(https://github.com/Neilpang/acme.sh/wiki/%E8%AF%B4%E6%98%8E) 主要步骤: 安装 acme.sh 生成证书 copy 证书到 nginx/ap...

haoyuehong
15分钟前
2
0
微擎框架内如何根据media_id获取到微信图片的路径

微擎的框架内,图片选择后,获取的是那个字符串是media_id,相当于你这张图片在微信的图片服务器里面的id 要求是:获取https://mmbiz.qpic.cn/mmbiz_jpg/…… 微信图片的路径 而微信并没有根据m...

老bia同学
19分钟前
1
0
Spring boot中日期的json格式化

Model 在model层中,类的日期属性上面添加如下注解: @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss") 参考 Jackson Date格式化教程...

亚林瓜子
21分钟前
2
0
Eclipse:Failed to load the JNI shared library

1.问题背景: 由于我之前使用jdk1.9学习,当使用Luke的时候发现jdk版本过高,需要向下配置jdk,就向朋友拷了一个安装包。重新配置路径后,便开始报错。 2.问题描述: Failed to load the JNI...

tinder_boy
23分钟前
0
0
少儿学习编程课程是否真的适合七八岁的低龄儿童[图]

少儿学习编程课程是否真的适合七八岁的低龄儿童[图]: 天下熙熙皆为利来,天下攘攘皆为利往。 这几年来,乐高教育机构在国内如同雨后春笋般出现,当然关闭/转手的也很多。从教师角度来看,部...

原创小博客
28分钟前
1
0
ES12-词项查询

1.词项查询介绍 全文查询将在执行之前分析查询字符串,但词项级别查询将按照存储在倒排索引中的词项进行精确操作。这些查询通常用于数字,日期和枚举等结构化数据,而不是全文本字段。 或者,...

贾峰uk
36分钟前
2
0
http状态码与ajax的状态值

ajax状态值 1.1 200 & OK:状态请求成功

litCabbage
39分钟前
1
0
iOS动画效果合集、飞吧企鹅游戏、换肤方案、画板、文字效果等源码

iOS精选源码 动画知识运用及常见动画效果收集 3D卡片拖拽卡片叠加卡片 iFIERO - FLYING PENGUIN 飞吧企鹅SpriteKit游戏(源码) Swift封装的空数据提醒界面EmptyView 沙盒文件浏览与分享调试控...

sunnyaigd
43分钟前
2
0
AngularJS配置.run()块中设置路由事件的监听器以及过滤未经授权的请求

AngularJS中的run方法初始化全局数据,只对全局作用域起作用,如$rootScope.多个控制器之间可以共享数据,如下代码所示: <script type="text/javascript"> var m1 = angular....

孟飞阳
43分钟前
3
0
Java语言学习(十):输入/输出

Java中,I/O操作代表着输入、输出,Java所有的I/O机制都是基于数据流进行输入输出。java.io类包提供了很多的输入输出处理功能方法,大家可以参考下JDK文档中关于I/O的一些处理方法:JDK在线中...

海岸线的曙光
53分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部