Clozure CL中文版020:剖析

  • 0

Clozure CL中文版020:剖析

Category:帮助手册 Tags : 

剖析

使用Linux oprofile系统级分析器

oprofile 是一个系统级的分析器,可用于大多数现代Linux发行版。

这里没有真正记录oprofile及其配套程序的使用; 所描述的是一种生成符号信息的方法,该符号信息使得由opreport程序生成的概要分析摘要能够有意义地识别lisp函数。

生成用于oprofile的lisp映像

现代Linux使用’ELF’(可执行和链接格式)目标文件格式;如果该文件看起来是ELF目标文件并且它包含ELF符号信息,那么oprofile工具可以将符号名称与内存映射文件中的地址相关联。描述那些内存区域。所以,一般的想法是制作一个看起来像ELF共享库的lisp堆图像来欺骗 oprofile工具(我们实际上并没有通过ELF动态链接技术加载堆图像,但我们可以让它看起来像我们一样。)

先决条件

  • oprofile 本身,如果尚未预先安装,几乎可以通过您的发行版的包管理系统获得。
  • libelf,它提供了用于读取和编写ELF文件的实用程序(同样可能预先安装或可以轻松安装。)有些令人困惑的是,Linux上有两种libelf实现广泛使用,不同的发行版用不同的名称引用它们(它们可以作为’elfutils’软件包的一部分。)oprofile insterface旨在与libelf实现一起使用,其版本号目前约为147; 另一个(不兼容的)libelf实现的版本号大约为0.8。可能需要安装相应的开发包(-dev或-devel,usuallly)才能实际使用libelf共享库。

为Lisp函数生成ELF符号

为了创建可用于oprofile基于概要分析的lisp堆映像 ,我们需要:

  1. 加载我们想要分析的任何代码
  2. 生成一个文件,其中包含描述所有lisp函数的名称和地址的ELF符号信息。

这一步涉及到(来自Clozure CL内)

? (require “ELF”)

“ELF”

(“ELF”)

 

? (ccl::write-elf-symbols-to-file “home:elf-symbols”)

CCL :: WRITE-ELF-SYMBOLS-TO-FILE的参数可以是任何可写路径名。该函数将执行将lisp函数固定在内存中所需的任何操作(以便它们不会被GC移动),然后将ELF目标文件写入指定的路径名​​。这通常需要几秒钟。

  1. 生成一个lisp堆映像,其中前一步骤中生成的ELF符号被预先添加。

函数CCL:SAVE-APPLICATION提供了一个:PREPEND-KERNEL参数,它通常用于保存内核和堆映像占用单个文件的独立应用程序。:PREPEND-KERNEL并不关心图像前面的内容,我们可以很容易地要求它预先添加上一步生成的ELF符号文件。

? (save-application “somewhere/image-for-profiling”    :prepend-kernel “home:elf-symbols”)

如果你然后运行

shell> ccl64 somewhare/image-for-profiling

由该图像中的oprofile采样的任何lisp代码将被“符号”地标识opreport。

;;; Define some lisp functions that we want to profile and save

;;; a profiling-enabled image.  In this case, we just want to

;;; define the FACTORIAL funcion, to keep things simple.

? (defun fact (n) (if (zerop n) 1 (* n (fact (1- n)))))

FACT

? (require “ELF”)

“ELF”

(“ELF”)

? (ccl::write-elf-symbols-to-file “home:elf-symbols”)

“home:elf-symbols”

? (save-application “home:profiled-ccl” :prepend-kernel “home:elf-symbols”)

 

;;; Setup oprofile with (mostly) default arguments.  This example was

;;; run on a Fedora 8 system where an uncompressed ‘vmlinux’ kernel

;;; image isn’t readily available.

 

;;; Note that use of ‘opcontrol’ generally requires root access, e.g.,

;;; ‘sudo’ or equivalent:

 

[~] gb@rinpoche> sudo opcontrol –no-vmlinux –setup

 

;;; Start the profiler

 

[~] gb@rinpoche> sudo opcontrol –start

Using 2.6+ OProfile kernel interface.

Using log file /var/lib/oprofile/samples/oprofiled.log

Daemon started.

Profiler running.

 

;;; Start CCL with the “profiled-ccl” image created above.

;;; Invoke “(FACT 10000)”

 

[~] gb@rinpoche> ccl64 profiled-ccl

Welcome to Clozure Common Lisp Version 1.2-r9198M-trunk  (LinuxX8664)!

? (null (fact 10000))

NIL

? (quit)

 

;;; We could stop the profiler (opcontrol –stop) here; instead,

;;; we simply flush profiling data to disk, where ‘opreport’ can

;;; find it.

 

 

[~] gb@rinpoche> sudo opcontrol –dump

 

;;; Ask opreport to show us where we were spending time in the

;;; ‘profiled-ccl’ image.

 

[~] gb@rinpoche> opreport -l profiled-ccl | head

CPU: Core 2, speed 1596 MHz (estimated)

Counted CPU_CLK_UNHALTED events (Clock cycles when not halted) with a unit mask of 0x00 (Unhalted core cycles) count 100000

samples  %        symbol name

6417     65.2466  <Compiled-function.(:INTERNAL.MULTIPLY-UNSIGNED-BIGNUM-AND-1-DIGIT-FIXNUM.MULTIPLY-BIGNUM-AND-FIXNUM).(Non-Global)..0x30004002453F>

3211     32.6487  <Compiled-function.%MULTIPLY-AND-ADD4.0x300040000AAF>

17        0.1729  <Compiled-function.%%ONE-ARG-DCODE.0x3000401740AF>

11        0.1118  <Compiled-function.%UNLOCK-RECURSIVE-LOCK-OBJECT.0x30004007F7DF>

10        0.1017  <Compiled-function.AUTO-FLUSH-INTERACTIVE-STREAMS.0x3000404ED6AF>

7         0.0712  <Compiled-function.%NANOSLEEP.0x30004040385F>

7         0.0712  <Compiled-function.%ZERO-TRAILING-SIGN-DIGITS.0x300040030F3F>

问题

CCL :: WRITE-ELF-SYMBOLS-TO-FILE目前仅适用于x86-64; 它当然可以用于ppc32 / ppc64。

到目前为止,还没有人能够生成oprofile / opreport选项,它们应该生成调用堆栈信息,生成有意义的调用堆栈信息。

截至几个月前,曾尝试“动态”提供oprofile / opreport的符号信息,例如,用于JIT编译或其他增量编译方案。这显然更接近The Right Thing,但在实验代码广泛使用之前可能需要一段时间。

使用Apple的CHUD计量工具

Apple的CHUD包提供了库,内核扩展以及一组图形和命令行程序,可用于测量应用程序和系统性能的许多方面。

其中一个程序是Shark应用程序(通常安装在“/ Developer / Applications / Performance Tools / Shark.app”中),它提供了一个图形用户界面,用于探索和分析性能分析结果,并提供用于创建“采样配置”的工具(请参阅以下),除其他外。这里没有真正记录Shark的使用(可以在“Developer / Documentation / CHUD / Shark / SharkUserGuide.pdf”中找到Shark手册); 所描述的是一种提供有关Lisp函数名称和地址的信息的方法,以便Shark可以在其输出中有意义地识别这些函数。

先决条件

Apple的CHUD工具已经与最新的几个XCode版本一起发布。确定是否安装工具的一种方法是运行:

$ /usr/bin/shark -v

在终端或Emacs shell缓冲区中。如果返回输出就像

shark 4.7.3 (365)

然后安装CHUD包。输出就像

shark: Command not found.

强烈暗示它不是……

生成用于Shark的lisp图像

Shark只能正确识别在目标应用程序加载的共享库中定义的函数。(任何其他函数将由描述为“未知库”的十六进制地址标识;十六进制地址通常稍微接近实际函数,但它是启发式确定的并且并不总是准确的。)

出于这些原因,需要在一个lisp会话中加载您希望分析的代码,保存本机(Mach-O库)映像,并在使用该本机映像的新会话中调用Shark。(加载CHUD-METERING模块也很有用,它定义了CHUD:METER和朋友。

用法简介

[src/ccl-dev] gb@antinomial> ccl64Welcome to Clozure Common Lisp Version 1.7-dev-r14624M-trunk  (DarwinX8664)!? (defun fact(n) (if (zerop n) 1 (* n (fact (1- n)))))FACT? (require “CHUD-METERING”)”CHUD-METERING”(“CHUD-METERING”)? (save-application “ccl:dx86cl64.dylib” :native t)[src/ccl-dev] gb@antinomial> ccl64 -I dx86cl64.dylibWelcome to Clozure Common Lisp Version 1.7-dev-r14624M-trunk  (DarwinX8664)!? (chud:meter (dotimes (i 1000) (fact 1000)));;; Waiting for shark to process samples …done.NIL

并且,在返回结果几秒后,将在Shark.app中打开名称格式为“session_nnn.mshark”的文件。

第一次将CHUD:METER用于lisp会话时,它会做一些事情来准备后续的分析会话。那些东西包括:

  • 创建一个目录来存储与在此lisp会话中使用CHUD工具相关的文件。此目录在用户的主目录中创建,并具有以下格式的名称:

profiling-session-<lisp-kernel>-<pid>_<mm>-<dd>-<yyyy>_<h>.<m>.<s>

  • 运行鲨鱼程序(“/ usr / bin / shark”)并等待它准备好接收控制其操作的信号。

这种启动活动通常需要几秒钟; 在完成之后,随后使用CHUD:METER不涉及这种开销。(参见下面的讨论:RESET。)

任何启动活动完成后,CHUD:METER安排向正在运行的鲨鱼程序发送“开始分析”信号,执行表单,向鲨鱼程序发送“停止分析”信号,并读取其诊断输出,查找它生成的“.mshark”文件的名称。如果它能够找到这个文件名,它会安排“Shark.app”打开它。

分析“配置”

默认情况下,鲨鱼分析会话将:

  • 使用“基于时间”的采样,定期中断lisp进程并记录程序计数器的值和至少几个级别的调用历史记录。
  • 每毫秒进行一次采样
  • 运行最多30秒,除非被告知要提前停止。

这被称为“默认配置”; 可以使用Shark应用程序中“配置”菜单上的项目来创建备用配置,这些配置提供不同类型的配置文件参数,并将这些配置保存在文件中以供后续重用。(CHUD知道如何监控的一组内容非常有趣。)

您使用备用配置文件配置(通过Shark.app创建和“导出”)与CHUD:METER,但界面有点尴尬。

参考

chud:*shark-config-file*[变量]

当非null时,这应该是Shark.app中“配置编辑器”创建的备用性能分析配置文件的路径名。

chud:meter form &key (reset nil)(debug-output nil)[Macro]

执行FORM(任意lisp表单)并返回它返回的任何结果,并在表单执行期间启用CHUD分析。尝试确定shark程序写入分析数据的会话文件(* .mshark)的名称,并在Shark应用程序中打开此文件。

参数:

调试输出

当非零时,导致鲨鱼程序生成的输出回显到* TERMINAL-IO *。用于调试。

重启

当非nil时,终止由此lisp会话中先前调用CHUD:METER创建的任何正在运行的shark程序实例,生成一个新的.spatch文件(描述lisp函数的名称和地址),并启动一个新的实例鲨鱼计划; 如果CHUD:* SHARK-CONFIG-FILE *在启动此新实例时为非NIL,则会告知该实例使用指定的配置文件进行性能分析(代替默认的性能分析配置)。

承认

Dan Knapp和Hamilton Link都在过去向openmcl-devel发布了类似的CHUD接口; 汉密尔顿还报告了CHUD开发人员的spatch机制中的错误(并修复了这些错误。)


Leave a Reply

搜索

分类目录

公 告

本网站学习论坛:

www.zhlisp.com

lisp中文学习源码:

https://github.com/zhlisp/

欢迎大家来到本站,请积极评论发言;

加QQ群学习交流。