使用stapxx和nginx-systemtap-toolkit进行优化的问题

354 views
Skip to first unread message

李辉

unread,
Dec 23, 2014, 10:17:40 PM12/23/14
to open...@googlegroups.com
hello agentzh,
    最近使用nginx-lua进行开发,其性能是很不错的但是后来在youtube上面看到你关于Nginx的演讲里面有提到stapxx和nginx-systemtap-toolkit,按照官方的文档重新编译了luajit和nginx开始使用flame graph进行分析,但是遇到了一些问题:
    1. flame graph(使用lj-lua-stacks.sxx)的调用栈有时候会出现问题比如在lj_alloc_free上方会出现content_by_lua的flame,这样一来调用关系就有点乱。
    2. 使用lj-vm-states时,其结果是
       C Code (by interpreted Lua): 74% (5026 samples)
       Interpreted: 11% (803 samples)
       Compiled: 9% (612 samples)
       Garbage Collector (not compiled): 3% (205 samples)
       Garbage Collector (compiled): 0% (58 samples)
       Trace exiting: 0% (23 samples)

   根据文档的说法是,compiled的比例过低是存在优化的空间,但是问题是如何确定那部分代码是需要优化的。有时候ffi调用,属于compiled,有时候则是C Code(测试了一个hash算法,ffi调用的),因此如何让c code变成compiled而不是C Code?
  谢谢!

Yichun Zhang (agentzh)

unread,
Dec 23, 2014, 10:31:11 PM12/23/14
to openresty
Hello!

2014-12-23 19:17 GMT-08:00 李辉:
> 1. flame
> graph(使用lj-lua-stacks.sxx)的调用栈有时候会出现问题,比如在lj_alloc_free上方会出现content_by_lua的flame,这样一来调用关系就有点乱。

请确保你使用的是 LuaJIT 2.1,因为 lj-lua-stacks 工具是针对 LuaJIT 2.1 的。较新版本的
OpenResty 中自带的 LuaJIT 都是 v2.1 版本的。

如果不是因为使用了 LuaJIT 2.0 的缘故,请提供你原始的 SVG 格式的火焰图文件。

> 2. 使用lj-vm-states时,其结果是
> C Code (by interpreted Lua): 74% (5026 samples)
> Interpreted: 11% (803 samples)
> Compiled: 9% (612 samples)
> Garbage Collector (not compiled): 3% (205 samples)
> Garbage Collector (compiled): 0% (58 samples)
> Trace exiting: 0% (23 samples)
>

显然,只有极少数的热 Lua 代码路径被实际 JIT 编译;换言之,绝大部分的 CPU 时间都花在了解释执行的 Lua 代码上面。

>
> 根据文档的说法是,compiled的比例过低是存在优化的空间,但是问题是如何确定那部分代码是需要优化的。

有多种分析办法。

首先,可以使用 lj-lua-stacks 工具分别作出解释部分的 Lua 火焰图和 JIT 部分的 Lua
火焰图,这样你可以知道哪些热代码路径是解释执行的,哪些是 JIT编译过的。具体见其官方文档中对 --arg nojit=1 和 --arg
nointerp=1 这两个命令行选项的解释:

https://github.com/openresty/stapxx#lj-lua-stacks

更进一步地,可以使用 LuaJIT 自带的 jit.v 或者 jit.dump 模块进行分析。它们会给出 JIT 编译被中断(即 trace
abort)的具体位置和原因。例如可以这么配置:

init_by_lua '
local v = require "jit.v"
v.on("/tmp/v.log")
';

用足够多的请求预热之后,检查 /tmp/v.log 文件里的输出即可。

使用 jit.dump 可以得到更多的细节:

local dump = require "jit.dump"
dump.on("b", "/tmp/dump.log")

由于 LuaJIT 的 JIT 编译器并不支持所有的原语,所以当它遇见它不支持的原语(即 NYI)时,便会自动中断 JIT 编译过程。关于
LuaJIT 的 JIT 编译器不支持哪些原语,支持哪些原语,可以参见下面这一篇官方文档:

http://wiki.luajit.org/NYI

显然,LuaJIT 2.1 比 2.0 支持编译更多的原语。

> 有时候ffi调用,属于compiled,有时候则是C
> Code(测试了一个hash算法,ffi调用的),因此如何让c code变成compiled而不是C Code?

见上。

值得一提的是,使用 lua-resty-core 库可以让很多 ngx_lua 提供的 Lua API 变得可以被 JIT 编译。只需在
init_by_lua 里加一行 require "resty.core" 就 OK 了。

Regards,
-agentzh

李辉

unread,
Dec 30, 2014, 10:44:00 PM12/30/14
to open...@googlegroups.com
hello,
    按照你所说的办法进行分析和优化,确实会使compiled的比率上升,但是在研究jit.dump的时候,有时候的trace abort是NYI,有时候则是inner loop in root trace,是不是就是说嵌套的循环的内层循环compile失败了?还有一个比较奇怪的是blacklisted,abort的地方就是一个array2hash,用的ipairs,代码是
    for _, v in ipairs(a) do
        h[tostring(v)] = 1
    end
可是结果还是编译中断了,不明白是怎么回事。

Best Regards.


--
--
邮件来自列表“openresty”,专用于技术讨论!
订阅: 请发空白邮件到 openresty...@googlegroups.com
发言: 请发邮件到 open...@googlegroups.com
退订: 请发邮件至 openresty+...@googlegroups.com
归档: http://groups.google.com/group/openresty
官网: http://openresty.org/
仓库: https://github.com/agentzh/ngx_openresty
教程: http://openresty.org/download/agentzh-nginx-tutorials-zhcn.html

Yichun Zhang (agentzh)

unread,
Jan 2, 2015, 4:34:41 PM1/2/15
to openresty
Hello!

2014-12-30 19:43 GMT-08:00 李辉:
> 但是在研究jit.dump的时候,有时候的trace
> abort是NYI,

我之前推荐使用 LuaJIT 2.1 就是因为 2.1 中的 NYI 比 2.0 少得多。另外,lua-resty-core 库也会明显减少
ngx_lua 的 Lua API 里的 NYI.

> 有时候则是inner loop in root
> trace,是不是就是说嵌套的循环的内层循环compile失败了?

这种 trace abort 是正常情况,可以忽略。因为外层循环在这一次尝试中被选作 root trace,而 root trace
不能有嵌套循环。JIT 编译器下一次尝试时就可能会把最内层的循环作为 root trace,那时就不会 abort 了。

> 还有一个比较奇怪的是blacklisted,abort的地方就是一个array2hash,用的ipairs,代码是
> for _, v in ipairs(a) do
> h[tostring(v)] = 1
> end
> 可是结果还是编译中断了,不明白是怎么回事。
>

你需要查看 trace abort 的具体理由。你这一段代码单独测试是可以同时被 LuaJIT 2.0 和 2.1 JIT 编译的:

$ luajit -jv -e 'local a = {} for i = 1, 500 do a[i] = i end local h =
{} for _, v in ipairs(a) do h[tostring(v)] = 1 end'
[TRACE 1 (command line):1 loop]
[TRACE 2 (command line):1 loop]

Regards,
-agentzh

李辉

unread,
Jan 5, 2015, 3:02:36 AM1/5/15
to open...@googlegroups.com
hello!
    目前来说,问题是解决了。
    谢谢。


Regards,
-agentzh

Reply all
Reply to author
Forward
0 new messages