首页 > 解决方案 > 为什么 ls 的这些指令计数差异如此之大?(ptrace vs perf vs qemu)

问题描述

我想计算运行 /bin/ls 时执行的指令总数。我使用了 3 种结果差异很大的方法,我不知道为什么。

1. 使用 ptrace 进行指令计数

我编写了一段代码,它调用 ls 的一个实例并使用 ptrace 单步执行它:

#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
#include <sys/reg.h>    
#include <sys/syscall.h>

int main()
{   
    pid_t child;
    child = fork(); //create child
    
    if(child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        char* child_argv[] = {"/bin/ls", NULL};
        execv("/bin/ls", child_argv);
    }
    else {
        int status;
        long long ins_count = 0;
        while(1)
        {
            //stop tracing if child terminated successfully
            wait(&status);
            if(WIFEXITED(status))
                break;

                ins_count++;
                ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
        }

    printf("\n%lld Instructions executed.\n", ins_count);

    }
    
    return 0;
}

运行这段代码给了我 516.678 条指令。

2.QEMU单步

我在单步模式下使用 qemu 模拟 ls 并使用以下命令将所有传入指令记录到日志文件中: qemu-x86_64 -singlestep -D logfile -d in_asm /bin/ls

根据 qemuls 执行 16.836 条指令。

3.性能

须藤性能统计

这个命令给了我 8.162.180 条指令执行。

我知道这些指令中的大多数来自动态链接器,它们被计算在内很好。但为什么这些数字相差如此之大?他们不应该都一样吗?

标签: clinuxqemuperfptrace

解决方案


为什么这些指令计数差异如此之大?因为他们真正衡量的东西不同,只有衡量的单位是一样的。就好像你在称你从商店里拿来的东西,一个人称所有的东西都没有包装,甚至没有贴纸,另一个人称它在包装中,也包括购物袋,还有一个人还加了你带来的泥土。房子在你的靴子上。

这几乎就是这里发生的事情:指令计数不仅仅是ls二进制文件中的指令计数,还可以包括它使用的库、引入这些库所需的内核加载器的服务,以及最后执行的代码在进程中,但在内核上下文中。在这方面,您使用的方法都表现不同。所以问题是:你需要从那个测量中得到什么?如果你需要“总的努力”,那么最大的肯定就是你想要的:这将包括内核造成的一些开销。如果您需要“我只想知道发生了什么ls”,那么最小的数字就是您想要的。


推荐阅读