首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >快速计算C程序中执行的指令数的方法

快速计算C程序中执行的指令数的方法
EN

Stack Overflow用户
提问于 2012-11-09 18:02:56
回答 5查看 15.6K关注 0票数 9

在执行C程序时,是否有一种简单的方法可以快速计算执行的指令数(x86指令--每个指令的数量和数量)?

我在gcc version 4.7.1 (GCC)机器上使用x86_64 GNU/Linux

EN

回答 5

Stack Overflow用户

发布于 2020-11-16 18:10:10

perf_event_open config = PERF_COUNT_HW_INSTRUCTIONS调用Linux 系统

这个Linux系统调用似乎是性能事件的跨架构包装器,包括来自CPU的硬件性能计数器和来自内核的软件事件。

下面是一个来自man perf_event_open页面的示例:

perf_event_open.c

代码语言:javascript
运行
复制
#define _GNU_SOURCE
#include <asm/unistd.h>
#include <linux/perf_event.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <inttypes.h>
#include <sys/types.h>

static long
perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
                int cpu, int group_fd, unsigned long flags)
{
    int ret;

    ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
                    group_fd, flags);
    return ret;
}

int
main(int argc, char **argv)
{
    struct perf_event_attr pe;
    long long count;
    int fd;

    uint64_t n;
    if (argc > 1) {
        n = strtoll(argv[1], NULL, 0);
    } else {
        n = 10000;
    }

    memset(&pe, 0, sizeof(struct perf_event_attr));
    pe.type = PERF_TYPE_HARDWARE;
    pe.size = sizeof(struct perf_event_attr);
    pe.config = PERF_COUNT_HW_INSTRUCTIONS;
    pe.disabled = 1;
    pe.exclude_kernel = 1;
    // Don't count hypervisor events.
    pe.exclude_hv = 1;

    fd = perf_event_open(&pe, 0, -1, -1, 0);
    if (fd == -1) {
        fprintf(stderr, "Error opening leader %llx\n", pe.config);
        exit(EXIT_FAILURE);
    }

    ioctl(fd, PERF_EVENT_IOC_RESET, 0);
    ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);

    /* Loop n times, should be good enough for -O0. */
    __asm__ (
        "1:;\n"
        "sub $1, %[n];\n"
        "jne 1b;\n"
        : [n] "+r" (n)
        :
        :
    );

    ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
    read(fd, &count, sizeof(long long));

    printf("Used %lld instructions\n", count);

    close(fd);
}

编译和运行:

代码语言:javascript
运行
复制
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o perf_event_open.out perf_event_open.c
./perf_event_open.out

输出:

代码语言:javascript
运行
复制
Used 20016 instructions

因此我们看到,结果非常接近于__asm__块中每个循环20000: 10k *两个指令的期望值(subjne)。

如果我改变了参数,即使是低值,如100

代码语言:javascript
运行
复制
./perf_event_open.out 100

它规定:

代码语言:javascript
运行
复制
Used 216 instructions

保持不变的+ 16指令,所以它的准确性似乎是相当高,这16必须只是ioctl设置指令后,我们的小循环。

现在,您可能还会对以下内容感兴趣:

本系统调用可以衡量的其他感兴趣的事件:

在Ubuntu20.04 amd64、GCC 9.3.0、Linux5.4.0、IntelCorei7-7820HQCPU上进行了测试。

票数 5
EN

Stack Overflow用户

发布于 2016-12-18 23:44:11

您可以使用硬件性能计数器(HPC)轻松地计算已执行指令的数量。为了访问HPC,您需要一个接口。我建议您使用PAPI性能API。

票数 2
EN

Stack Overflow用户

发布于 2019-06-22 07:56:26

英特尔Pin的instcount

您可以使用由英特尔的二进制仪器工具'引脚‘。我会避免使用模拟器(它们通常非常慢)。Pin做了大部分你可以用模拟器做的事情,而不需要重新编译二进制文件,并且像速度一样以正常的速度执行(取决于你使用的引脚工具)。

若要使用Pin计数指令数,请执行以下操作:

  1. 下载最新的(或3.10,如果这个答案老了)别针套件从这里。
  2. 提取所有内容并转到目录:cd pin-root/source/tools/ManualExample/
  3. 使目录中的所有工具:make all
  4. 使用命令:../../../pin -t obj-intel64/inscount0.so -- your-binary-here运行一个名为inscount0.so的工具
  5. inscount.outcat inscount.out文件中获取指令计数。

输出将类似于:

代码语言:javascript
运行
复制
➜ ../../../pin -t obj-intel64/inscount0.so -- /bin/ls
buffer_linux.cpp       itrace.cpp
buffer_windows.cpp     little_malloc.c
countreps.cpp          makefile
detach.cpp         makefile.rules
divide_by_zero_unix.c  malloc_mt.cpp
isampling.cpp          w_malloctrace.cpp
➜ cat inscount.out
Count 716372
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13313510

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档