Profile 分析 Erlang 虚拟机源码时要注意的一个问题
最近用 Intel Vtune 剖析 Erlang 虚拟机的运行,想看看那些函数和语句耗时最多,遇到一个小问题,那就是 Vtune 给出的源码和汇编码对应有问题。这个问题在 profile 或 debug 其他程序的时候也有可能会碰到的。
看下面的例子,运行 dialyzer 的时候用 Vtune 进行采样,然后看结果:

很自然,process_main 函数耗时最多,是 CPU 主要利用者,因为整个 Erlang 虚拟机的指令执行引擎都在这个函数中。那么双击这个函数,进去看详细的源代码的耗时信息,会看到奇怪的现象:

可以看到第 12 行的注释和下面的 #include 指令竟然耗时间了,更神奇的是,这些源码行还输出了汇编,比如第 12 行对应右边的 mov 指令。还有下图中,第 38 行的 #include 生成这么多汇编码也是不可能的:

这会不会是和宏展开相关呢?会不会是和编译器的优化相关呢?会不会是编译器弄错了呢?
以上问题的答案都是否定的。因为这个文件(beam_emu.c)宏展开也不会在第 12 行有代码。而且编译器不会这么笨的。优化也不可能,因为我没开优化,为了详细观察语句(对应指令)执行耗时情况,关闭了优化(-O0),而且请求编译器包含最丰富的调试信息(-g3)。也不太可能是编译器弄错了,因为 gcc 和 Intel 的 icc 都出现了这个现象,而且都是在同样的位置。假设真的是编译器弄错了,那么完全不同的编译器也不太可能会错成一样,所以感觉这里肯定是有确定性原因的。
那到底是怎么回事呢?用 objdump -S 导出目标文件 beam_emu.o 的源码和汇编码信息,可以看出编译器是很忠诚的,没有奇怪的问题,而且很显然那些注释和 #include 指令那些地方是没有输出汇编代码的,编译器既然能在目标文件中内嵌正确的源码信息,那就不太可能会弄错行号。那就看看第 12 行对应的汇编码到底对应的源码是什么。下图中框出来的 3 条汇编指令是 NextPF 宏生成的,中间那一条就是之前图中在 0x5d7e6c 处对应第 12 行的那条汇编。

那就找这几行源代码在 beam_emu.c 中对应的位置应该就可以看出究竟了。有趣的是,在 beam_emu.c 中其实找不到这几行代码。beam_emu.c 把一些热门指令的代码单独放在 beam_hot.h 文件中了,这个文件是在 build 过程中自动生成的。果然,在这个文件中看到了这段代码:

哈,找到原因了。调用 NextPF 宏的刚好是第 12 行,原来编译器记录的是被包含文件中的行数。当然这并不是编译器的处理方式不对,而是这种将源代码 #include 到另一个源代码文件中的做法本身不是一个好的编程习惯,但是鉴于 process_main 的特殊性,这有助于保持代码的简洁(尽管这样 process_main 还是有好几千行)。
注意,这里的代码映射错误的问题并不是 Vtune 的问题,Vtune 只是忠实地反映出目标文件中调试信息里面的内容,而调试信息是编译器生成的。
那么为了能在 profile 过程中准确对应到源码行,我们手工把 beam_hot.h 文件的内容(还有 beam_cold.h,对应冷门指令)拷贝到 beam_emu.c 中对应的位置并重新 build 即可。再次运行 profile,可以看出代码映射完全正确了:

对右侧的汇编指令的耗时排序:

可以看出跳转指令的开销还是不小的,因为虚拟机每执行下一条指令都是一个跳转。所以 Erlang 虚拟机中的指令数目也非常多,每一条都尽量完成尽可能多的工作,以减少指令分发的次数。
Profile 分析 Erlang 虚拟机源码时要注意的一个问题的更多相关文章
- 分析jQuery源码时记录的一点感悟
分析jQuery源码时记录的一点感悟 1. 链式写法 这是jQuery语法上的最大特色,也许该改改POJO里的set方法,和其他的非get方法什么的,可以把多行代码合并,减去每次 ...
- IDEA查看源码时提示:Library source does not match the bytecode for class的问题分析
通过Maven查看依赖的源码时,通常是Maven自动下载JAR包附属的source包,但是会出现一个问题,由于使用lombok插件会造成编写的Java文件和编译后的class上有差别,所以IDEA打开 ...
- Spring Ioc源码分析系列--Ioc源码入口分析
Spring Ioc源码分析系列--Ioc源码入口分析 本系列文章代码基于Spring Framework 5.2.x 前言 上一篇文章Spring Ioc源码分析系列--Ioc的基础知识准备介绍了I ...
- [Erlang 0119] Erlang OTP 源码阅读指引
上周Erlang讨论群里面提到lists的++实现,争论大多基于猜测,其实打开代码看一下就都明了.贴出代码截图后有同学问这代码是哪里找的? "代码去哪里找?",关于Erla ...
- Android5.1.1 - APK签名校验分析和修改源码绕过签名校验
Android5.1.1 - APK签名校验分析和修改源码绕过签名校验 作者:寻禹@阿里聚安全 APK签名校验分析 找到PackageParser类,该类在文件“frameworks/base/cor ...
- JPEG概述和头分析(C源码)
原创文章,转载请注明:JPEG概述和头分析(C源码) By Lucio.Yang 部分内容来自:w285868925,JPEG压缩标准 1.JPEG概述 JPEG是一个压缩标准,又可分为标准 JPE ...
- [strongswan][autoconf][automake][cento] 在CentOS上编译strongswan git源码时遇到的autoconf问题
编译strongswan的git源码问题 1. 概述 首先,我们想要通过源码编译strongswan.当满足以下条件时,通常你会遇见此问题: 源码时通过git clone的得来的,而不是官网下载的源码 ...
- Cesium专栏-填挖方分析(附源码下载)
Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以 ...
- Proxy Server源码及分析(TCP Proxy源码 Socket实现端口映射)
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/u014530704/article/de ...
随机推荐
- 一个android应用开发的感悟
对于客户端的开发,以我个人现在的水准,很难进行一个系统的讲解,只能分享下遇到的几个问题点好了! 1:对于tabhost的使用,这个东西真的是过时了:第一个版本,我是用的tabhost确实是很难用,不过 ...
- Qt之QAbstractItemView视图项拖拽(二)
一.需求说明 上一篇文章Qt之QAbstractItemView视图项拖拽(一)讲述了实现QAbstractItemView视图项拖拽的一种方式,是基于QDrag实现的,这个类是qt自己封装好了的,所 ...
- 【原创】网站抓包HttpWebRequest不返回Javascript生成的Cookie的解决办法
前言: 最近在做中国移动爬虫的过程中,首先遇到的就是 在某个请求中,有一个名为“WT_PFC"的cookie键值是由前端JavaScript生成的,没有进入到HttpWebResponse中 ...
- Ajax学习资源大全[本来是转载的,但是现在我增加了很多]
本欲放转载区,但是这样一文章放那里基本是没有用的,帮助不了任何人!所以放新手了!! 我一般非经典或者自己用不上不转载,所以如果你不幸看见了的话,恰恰你又对AJAX有兴趣的话不防看下,也许对你有用的!! ...
- springMVC全局Exception异常处理SimpleMappingExceptionResolver
继承了SimpleMappingExceptionResolver 贴上代码 /** * 对controller异常进行全局处理 * 区分了对普通请求和ajax请求的异常处理,普通请求返回到配置的er ...
- [moka同学笔记]bootstrap基础
1.导航栏的制作 <nav class="nav navbar-default navbar-fixed-top" role="navigation"&g ...
- (旧)子数涵数·PS——换脸
一.打开Photoshop,打开下载好的两张素材图(均在百度下载的). 二.选中人物脸的部分,不需要很精确(哪种抠图方式都行,我用的是矩形选框工具),再使用移动工具(快捷键为V,或者按着Ctrl),将 ...
- Python关键字参数
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict.请看示例: #!/usr/bin/env python # -*- coding: utf-8 -*- ...
- [Tool] 使用Astah绘制UML图形
[Tool] 使用Astah绘制UML图形 前言 在软件开发的过程中,开发人员可以绘制UML图形来将分析设计内容转化为图形化文件,方便在团队之间传递分析设计结果.但在团队经费有限的情景中,可能没办法为 ...
- 【基础】PHP变量及变量作用域
新学PHP,比较有意思的语法,记录下. 1. 变量的作用域 作用域只分两个Global和Local,Global相对于整个.php文件来讲,Local是本地最小范围,是距离变量最近的范围,如:在函数中 ...