结合使用Perf和Python子过程模块来稳健或准确地描述系统性能的方法

时间:2018-08-15 07:36:04

标签: python linux subprocess perf

问题

在Python子进程模块中是否有任何可靠的方法来使用perf?

情况

我有一个app.py基准测试应用程序,并且一直在使用命令perf stat -e <some events> -- app.py,问题是当我使用此命令时,perf会在一开始就对其进行调查,但是有很多设置早期的东西。例如,

$ perf stat -e cycles -- app.py
Starting...
Setting 1...
Setting 2...
Setting 3...
Setting 4...
Setting 5...
---perf subprocess point that I'd like to put---
Another application or process comes up and real data transaction starts...

在这种情况下,起点和实际应用程序运行点之间存在巨大差距。关键是perf的目标应该是另一个应用程序(例如apachememcached),而不是为子级设置适当选项的父python应用程序(app.py)处理。因此,我想跳过这段时期并分析实际流程或子流程。

我尝试在子进程上下文中使用perf,但是当我使用它时会发生问题,因为perf在运行时受阻,直到我中断使用Ctrl-c时才继续进行

我还看过另一篇与我有同样问题的帖子,但是回答the question的作者似乎并不同意这种方式。 (我还没有尝试过,但似乎很棘手,所以我只想知道周围还有什么办法)

所以,如果有更好的选择,请告诉我。

更新

感谢Peter Cordes,我有了个主意。我不知道长期运行是什么意思,所以我搜索并发现了this link。我认为这可能是我代码的逻辑。我还在努力

1 个答案:

答案 0 :(得分:0)

代码

import os
import subprocess
import shlex
import signal

class Perf():
    __info__ = ["core", "file"]

    def __init__(self, core, file="log")
        self.__rootDir = "/"
        self.__p = None
        self.__core = core
        self.__file = __class_.__name__ + "." + file + ".core-" + core + ".csv"

    def start(self):
        path = os.path.join(self.__rootDir + self.__file)
        cmd = "perf stat -M CPU_Utilization -a -x , -o " + path
        args = shlex.split(cmd)
        self.__p = subprocess.Popen(args) # There are bunch of options

    def stop(self):
        os.kill(self.__p.pid, signal.SIGINT) # Instead of Popen.kill(), I use Ctrl-C
        self.__p = None

与其他帖子或答案几乎相同。我只是将其重新制作为class模块。我已经花了几个小时的时间,发现有些功能似乎很明显,您可能不知道。

  • 运行此Perf类时,应放置正确的路径。子进程可以在任何地方运行,并且进程运行的时刻就是输出文件的位置。

  • 我发现这不能使perf完美地提高。初始化和数据事务的起点之间仍然存在间隙,这意味着即使perf立即开始对子进程或子应用程序进行概要分析,也存在空闲时间。

  • 需要改进此代码以支持PATH变量。我一直在尝试使用os.environ['PATH']来在系统范围内放置命令的另一条路径,但是仍然以某种方式仍然停留。