标签: perf

从perf获取用户空间堆栈信息

我正在尝试在我正在测试的PostgreSQL构建中跟踪一些幻像I/O. 它是一个多进程服务器,将磁盘I/O关联回特定的后端和查询并不简单.

我认为Linux的perf工具对此非常理想,但我正在努力捕获块I/O性能计数器指标并将它们与用户空间活动相关联.

通过以下方式记录块I/O请求和完成很容易:

sudo perf record -g -T -u postgres -e 'block:block_rq_*'
Run Code Online (Sandbox Code Playgroud)

并且记录了用户空间pid,但是没有捕获内核或用户空间堆栈,或者能够对用户空间进程堆的快照位(例如,查询文本)等进行快照.所以当你有pid时,你就不会我知道那个过程在那一点上做了什么.只是perf script输出,如:

postgres  7462 [002] 301125.113632: block:block_rq_issue: 8,0 W 0 () 208078848 + 1024 [postgres]
Run Code Online (Sandbox Code Playgroud)

如果我向其添加-g标志,perf record则会获取内核堆栈的快照,但不会捕获内核中捕获的perf事件的用户空间状态.用户空间堆只上升到从用户空间,如入口点LWLockRelease,LWLockAcquire,memcpy(mmap'd IO),__GI___libc_write

所以.有小费吗?能够捕获用户空间堆栈的快照以响应内核事件将是理想的.

我在Fedora 19,3.11.3-201.fc19.x86_64,Schrödinger的Cat,使用perf版本3.10.9-200.fc19.x86_64.

c linux linux-kernel perf

11
推荐指数
1
解决办法
5217
查看次数

Perf启动开销:为什么执行MOV + SYS_exit的简单静态可执行文件有如此多的停顿周期(和指令)?

我试图了解如何衡量性能并决定编写非常简单的程序:

section .text
    global _start

_start:
    mov rax, 60
    syscall
Run Code Online (Sandbox Code Playgroud)

我用perf stat ./bin 这个程序运行我感到惊讶的stalled-cycles-frontend是太高了.

      0.038132      task-clock (msec)         #    0.148 CPUs utilized          
             0      context-switches          #    0.000 K/sec                  
             0      cpu-migrations            #    0.000 K/sec                  
             2      page-faults               #    0.052 M/sec                  
       107,386      cycles                    #    2.816 GHz                    
        81,229      stalled-cycles-frontend   #   75.64% frontend cycles idle   
        47,654      instructions              #    0.44  insn per cycle         
                                              #    1.70  stalled cycles per insn
         8,601      branches                  #  225.559 M/sec                  
           929      branch-misses             #   10.80% of all branches        

   0.000256994 seconds time elapsed …
Run Code Online (Sandbox Code Playgroud)

linux performance assembly x86-64 perf

11
推荐指数
1
解决办法
155
查看次数

如何提出高缓存未命中率的例子?

我试图想出一个具有高缓存未命中率的示例程序.我想我可以尝试逐列访问矩阵,如下所示:

#include <stdlib.h>

int main(void)
{
    int i, j, k;

    int w = 1000;
    int h = 1000;

    int **block = malloc(w * sizeof(int*));
    for (i = 0; i < w; i++) {
        block[i] = malloc(h * sizeof(int));
    }

    for (k = 0; k < 10; k++) {
        for (i = 0; i < w; i++) {
            for (j = 0; j < h; j++) {
                block[j][i] = 0;
            }
        }
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我使用-O0flag 编译它并使用perf …

c c++ caching perf

9
推荐指数
1
解决办法
2766
查看次数

perf是否锁定配置文件用户空间互斥?

摘要:perf lock配置文件pthread_mutex?

细节:

该工具perf有一个选项perf lock.手册页说:

You can analyze various lock behaviours and statistics with this perf lock command.
   'perf lock record <command>' records lock events
    between start and end <command>. And this command
    produces the file "perf.data" which contains tracing
    results of lock events.

    'perf lock trace' shows raw lock events.

    'perf lock report' reports statistical data.
Run Code Online (Sandbox Code Playgroud)

但是当我试着跑步时,perf lock record我得到一个错误说:invalid or unsupported event: 'lock:lock_acquire'.我看了,似乎错误可能是因为我的内核没有编译CONFIG_LOCKDEPCONFIG_LOCK_STAT. …

linux perf

9
推荐指数
1
解决办法
3006
查看次数

perf_event_open溢出信号

我想计算某些代码的(或多或少)确切数量的指令.此外,我希望在通过特定数量的指令后收到信号.

为此,我使用perf_event_open提供的溢出信号行为 .

我正在使用manpage建议实现溢出信号的第二种方式:

信号溢出

可以设置事件以在超过阈值时传递信号.使用poll(2),select(2),epoll(2)和fcntl(2),系统调用来设置信号处理程序.

[...]

另一种方法是使用PERF_EVENT_IOC_REFRESH ioctl.这个ioctl增加了一个计数器,每次事件溢出时减少.当非零时,溢出时发送POLL_IN信号,但一旦值达到0,就会发送类型为POLL_HUP的信号,并禁用基础事件.

PERF_EVENT_IOC_REFRESH ioctl的进一步说明:

PERF_EVENT_IOC_REFRESH

非继承溢出计数器可以使用它来为参数指定的多个溢出启用计数器,之后禁用它.此ioctl的后续调用将参数值添加到当前计数.设置POLL_IN的信号将在每次溢出时发生,直到计数达到0; 当发生这种情况时,发送设置了POLL_HUP的信号并禁用该事件.使用0的参数被视为未定义的行为.

一个非常小的例子看起来像这样:

#define _GNU_SOURCE 1

#include <asm/unistd.h>
#include <fcntl.h>
#include <linux/perf_event.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

long perf_event_open(struct perf_event_attr* event_attr, pid_t pid, int cpu, int group_fd, unsigned long flags)
{
    return syscall(__NR_perf_event_open, event_attr, pid, cpu, group_fd, flags);
}

static void perf_event_handler(int signum, siginfo_t* info, void* ucontext) {
    if(info->si_code != POLL_HUP) {
        // Only POLL_HUP should happen.
        exit(EXIT_FAILURE);
    }

    ioctl(info->si_fd, PERF_EVENT_IOC_REFRESH, 1); …
Run Code Online (Sandbox Code Playgroud)

linux signals perf

9
推荐指数
1
解决办法
3103
查看次数

有没有办法使用 perf 工具在进程中查找单个函数的性能?

我试图在一个过程中获得单个功能的性能。我怎样才能使用 perf 工具做到这一点?有没有其他工具可以做到这一点?

例如,假设 main 函数调用函数 A 、 B 、 C 。我想分别获得主要功能以及功能 A、B、C 的性能。

是否有一个很好的文档来低估 perf 源代码?

谢谢你。

linux profiling function perf

9
推荐指数
2
解决办法
5288
查看次数

Perf过度计算简单的CPU绑定循环:神秘的内核工作?

我已经使用Linux perf一段时间来进行应用程序分析.通常情况下,配置文件应用程序相当复杂,因此只要根据第一原则与您的预期没有任何严重差异,就可以简单地将报告的计数器值视为面值.

然而,最近,我已经描述了一些简单的64位汇编程序 - 足够的竞争,人们几乎可以计算各种计数器的预期值,而且似乎perf stat是过度计算.

以下面的循环为例:

.loop:
    nop
    dec rax
    nop
    jne .loop
Run Code Online (Sandbox Code Playgroud)

这将简单地循环n次数,其中n是初始值rax.循环的每次迭代都执行4条指令,因此您可以期望4 * n执行指令,加上一些用于进程启动和终止的固定开销,以及n在进入循环之前设置的一小段代码.

这是(典型)perf stat输出n = 1,000,000,000:

~/dev/perf-test$ perf stat ./perf-test-nop 1

 Performance counter stats for './perf-test-nop 1':

        301.795151      task-clock (msec)         #    0.998 CPUs utilized          
                 0      context-switches          #    0.000 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
                 2      page-faults               #    0.007 K/sec                  
     1,003,144,430      cycles                    #    3.324 GHz                      
     4,000,410,032      instructions …
Run Code Online (Sandbox Code Playgroud)

performance x86 assembly linux-kernel perf

9
推荐指数
1
解决办法
405
查看次数

在没有--privileged的情况下在docker容器中使用perf

我试图在Docker容器中使用perf工具来记录给定的命令.

kernel.perf_event_paranoid设置为1,但是当我没有放置--privileged标志时,容器的行为就像2那样.

我可以使用--privileged,但是我运行perf的代码不受信任,如果我通过允许perf工具承担轻微的安全风险,那么在容器上给予特权权限似乎是不同的风险级别.

有没有其他方法在容器内使用perf?

~$ docker version
Client:
 Version:      17.03.1-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   7392c3b/17.03.1-ce
 Built:        Tue May 30 17:59:44 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.03.1-ce
 API version:  1.27 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   7392c3b/17.03.1-ce
 Built:        Tue May 30 17:59:44 2017
 OS/Arch:      linux/amd64
 Experimental: false

~$ cat /proc/sys/kernel/perf_event_paranoid
1
~$ perf record ./my-executable
perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error 1 (Operation not permitted)
perf_event_open(..., 0) failed unexpectedly with error 1 (Operation not permitted) …
Run Code Online (Sandbox Code Playgroud)

linux privileges perf docker

9
推荐指数
1
解决办法
2893
查看次数

为什么perf有这么高的上下文切换?

我试图了解linux perf,发现一些非常令人困惑的行为:

我写了一个简单的多线程示例,其中一个线程固定到每个核心; 每个线程在本地运行计算,并且不相互通信(见test.cc下文).我在想这个例子应该有非常低的(如果不是零)上下文切换.但是,使用linux perf来分析示例显示了数千个上下文切换 - 远远超出了我的预期.我进一步分析了linux命令sleep 20以进行比较,显示更少的上下文切换.

此个人资料结果对我没有任何意义.什么导致如此多的上下文切换?

> sudo perf stat -e sched:sched_switch ./test
 Performance counter stats for './test':

                 6,725  sched:sched_switch                                          

      20.835 seconds time elapsed

> sudo perf stat -e sched:sched_switch sleep 20

 Performance counter stats for 'sleep 20':

                 1      sched:sched_switch                                          

      20.001 seconds time elapsed
Run Code Online (Sandbox Code Playgroud)

要重现结果,请运行以下代码:

perf stat -e context-switches sleep 20
perf stat -e context-switches ./test
Run Code Online (Sandbox Code Playgroud)

要编译源代码,请输入以下代码:

g++ -std=c++11 -pthread -o test test.cc
Run Code Online (Sandbox Code Playgroud)
// test.cc
#include <iostream>
#include <thread>
#include <vector> …
Run Code Online (Sandbox Code Playgroud)

c++ linux perf

9
推荐指数
2
解决办法
226
查看次数

每个mmap/access/munmap有两个TLB-miss

for (int i = 0; i < 100000; ++i) {
    int *page = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE,
                            MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);

    page[0] = 0;

    munmap(page, PAGE_SIZE);
}
Run Code Online (Sandbox Code Playgroud)

我期望在用户空间中获得~100000 dTLB-store-miss,每次迭代一次(同样~100000页错误和内核的dTLB-load-miss).运行以下命令,结果大约是我期望的2倍.如果有人能澄清为什么会这样,我将不胜感激:

perf stat -e dTLB-store-misses:u ./test
Performance counter stats for './test':

           200,114      dTLB-store-misses

       0.213379649 seconds time elapsed
Run Code Online (Sandbox Code Playgroud)

PS我已经验证并确定生成的代码没有引入任何可以证明这个结果的东西.此外,我确实得到~100000页错误和dTLB加载未命中:k.

c performance performancecounter tlb perf

8
推荐指数
1
解决办法
266
查看次数