相关疑难解决方法(0)

如何分析在Linux上运行的C++代码?

我有一个在Linux上运行的C++应用程序,我正在优化它.如何确定代码的哪些区域运行缓慢?

c++ unix profiling

1732
推荐指数
12
解决办法
49万
查看次数

每个汇编指令需要多少个CPU周期?

我听说有英特尔在线书籍描述了特定汇编指令所需的CPU周期,但我无法找到它(经过努力).有人能告诉我如何找到CPU周期吗?

下面是一个例子,在下面的代码中,mov/lock是1个CPU周期,xchg是3个CPU周期.

// This part is Platform dependent!
#ifdef WIN32
inline int CPP_SpinLock::TestAndSet(int* pTargetAddress, 
                                              int nValue)
{
    __asm
    {
        mov edx, dword ptr [pTargetAddress]
        mov eax, nValue
        lock xchg eax, dword ptr [edx]
    }
    // mov = 1 CPU cycle
    // lock = 1 CPU cycle
    // xchg = 3 CPU cycles
}

#endif // WIN32
Run Code Online (Sandbox Code Playgroud)

顺便说一句:这是我发布的代码的URL:http://www.codeproject.com/KB/threads/spinlocks.aspx

cpu assembly cycle

48
推荐指数
5
解决办法
5万
查看次数

使用gdb计算机器指令

我需要根据x86机器指令数来估计程序中某些热点的确切起始位置(以便稍后可以在某个仿真器/模拟器中运行).有没有办法使用gdb来计算执行到断点的机器指令的数量?

当然还有其他选择,我可以使用仿真/二进制检测工具(如Pin),并在计算指令时跟踪运行,但这需要在我工作的每个平台上安装此工具 - 并非总是可行.我需要一些可以在任何Linux机器上使用的工具.

用GDB,我想它也可以运行stepi X,直到我们遇到断点过大的进步是某种粗粒搜索,然后降低分辨率重复,但是这将是极为缓慢.还有另一种方法吗?

x86 trace gdb

14
推荐指数
3
解决办法
2807
查看次数

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
查看次数

在预测现代超标量处理器上的操作延迟时需要考虑哪些因素以及如何手动计算它们?

我希望能够手动预测任意算术的长度(即没有分支或内存,尽管这也很好)x86-64汇编代码将采用特定的体系结构,考虑到指令重新排序,超标量,延迟,消费者价格指数等

什么/描述必须遵循的规则才能实现这一目标?


我想我已经找到了一些初步规则,但是我没有找到任何关于将任何示例代码分解为这个详细程度的引用,所以我不得不做一些猜测.(例如,英特尔优化手册甚至几乎没有提到指令重新排序.)

至少,我正在寻找(1)确认每条规则是正确的,或者是每条规则的正确陈述,以及(2)我可能忘记的任何规则的列表.

  • 每个循环发出尽可能多的指令,从当前循环开始按顺序开始,并且可能与重新排序缓冲区大小一样远.
  • 如果出现以下情况,可以在给定周期发出指令:
    • 没有影响其操作数的指令仍在执行中.和:
    • 如果它是浮点指令,则它之前的每个浮点指令都被发出(浮点指令具有静态指令重新排序).和:
    • 该循环有一个功能单元可用于该指令.每个(?)功能单元是流水线的,这意味着它可以在每个周期接受1个新指令,并且对于给定功能类的CPI,总功能单元的数量是1/CPI(这里模糊不清:可能是例如addps并且subps使用相同的功能) unit?我如何确定?).和:
    • 4此循环已经发出少于超标量宽度(通常)指令的数量.
  • 如果不能发出指令,则处理器不会发出任何称为"停顿"的条件.

例如,请考虑以下示例代码(计算交叉产品):

shufps   xmm3, xmm2, 210
shufps   xmm0, xmm1, 201
shufps   xmm2, xmm2, 201
mulps    xmm0, xmm3
shufps   xmm1, xmm1, 210
mulps    xmm1, xmm2
subps    xmm0, xmm1
Run Code Online (Sandbox Code Playgroud)

我试图预测Haswell的延迟看起来像这样:

; `mulps`  Haswell latency=5, CPI=0.5
; `shufps` Haswell latency=1, CPI=1
; `subps`  Haswell latency=3, CPI=1

shufps   xmm3, xmm2, 210   ; cycle  1
shufps   xmm0, xmm1, 201   ; cycle  2
shufps   xmm2, xmm2, 201   ; …
Run Code Online (Sandbox Code Playgroud)

assembly pipeline latency x86-64 superscalar

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

Linux ldd 中的“静态链接”和“非动态可执行文件”有什么区别?

考虑这个 AMD64 汇编程序:

.globl _start
_start:
    xorl %edi, %edi
    movl $60, %eax
    syscall
Run Code Online (Sandbox Code Playgroud)

如果我编译gcc -nostdlib并运行ldd a.out,我得到这个:

        statically linked
Run Code Online (Sandbox Code Playgroud)

如果我改为使用gcc -static -nostdlib并运行编译它ldd a.out,我会得到这个:

        not a dynamic executable
Run Code Online (Sandbox Code Playgroud)

什么之间的区别statically linkednot a dynamic executable?如果我的二进制文件已经静态链接,为什么添加-static会影响任何事情?

linux gcc x86-64 static-linking ldd

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

Syscall实现exit()

我写了一个简单的C程序,只调用exit()函数,但是strace说二进制文件实际上是调用exit_group,exit()是一个exit_group()包装器吗?这两个功能是否相同?如果是这样,为什么编译器会选择exit_group()而不是exit()?

c x86 assembly gcc system-calls

6
推荐指数
1
解决办法
2300
查看次数

执行指令的数量与Hello World程序Nasm Assembly和C不同

我有一个简单的调试器(使用ptrace:http://pastebin.com/D0um3bUi)来计算给定输入可执行程序执行的指令数.它使用ptrace单步执行模式来计算指令.

为此,当程序1)的可执行文件(来自gcc main.c的a.out)作为输入提供给我的测试调试器时,它会在执行指令时打印大约100k.当我使用-static选项时,它会给出10681条指令.

现在在2)我创建一个汇编程序并使用NASM进行编译和链接,然后当这个可执行文件作为测试调试器输入时,它显示8个指令作为计数,哪个是apt.

程序1)中执行的指令数量很高,因为在运行时将程序与系统库链接起来了?使用-static并将计数减少1/10.如何确保指令计数仅是程序1)中主要功能的指令,以及程序2)为调试器报告的方式?

1)

#include <stdio.h>

int main()
{
    printf("Hello, world!\n");
    return 0;
}    
Run Code Online (Sandbox Code Playgroud)

我使用gcc来创建可执行文件.

2)

; 64-bit "Hello World!" in Linux NASM

global _start            ; global entry point export for ld

section .text
_start:

    ; sys_write(stdout, message, length)

    mov    rax, 1        ; sys_write
    mov    rdi, 1        ; stdout
    mov    rsi, message    ; message address
    mov    rdx, length    ; message string length
    syscall

    ; sys_exit(return_code)

    mov    rax, 60        ; sys_exit
    mov    rdi, …
Run Code Online (Sandbox Code Playgroud)

linux assembly gcc x86-64 nasm

5
推荐指数
2
解决办法
1198
查看次数

为什么运行一个空程序需要这么多指令?

所以最近学习了perflinux中的命令。我决定进行一些实验,因此我创建了一个空的 C 程序并测量了运行所需的指令数:

echo 'int main(){}'>emptyprogram.c && gcc -O3 emptyprogram.c -o empty
perf stat ./empty
Run Code Online (Sandbox Code Playgroud)

这是输出:

 Performance counter stats for './empty':

      0.341833      task-clock (msec)         #    0.678 CPUs utilized          
             0      context-switches          #    0.000 K/sec                  
             0      cpu-migrations            #    0.000 K/sec                  
           112      page-faults               #    0.328 M/sec                  
     1,187,561      cycles                    #    3.474 GHz                    
     1,550,924      instructions              #    1.31  insn per cycle         
       293,281      branches                  #  857.966 M/sec                  
         4,942      branch-misses             #    1.69% of all branches        

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

为什么它使用这么多指令来运行一个实际上什么也不做的程序?我认为这可能是将程序加载到操作系统中所需的一些基准指令数,因此我寻找了用汇编语言编写的最小可执行文件,并且发现了一个在此处输出的 142 字节可执行文件"Hi World"http://timelessname.txt)。 …

linux cpu assembly perf

5
推荐指数
1
解决办法
757
查看次数

基准测试 - 如何计算发送到 CPU 的指令数以查找消耗的 MIPS

假设我有一个软件,并且想要使用黑盒方法研究其行为。我有一个 3.0GHz CPU,有 2 个插槽和 4 个核心。如您所知,为了找出每秒指令数 (IPS),我们必须使用以下公式:

IPS = sockets*(cores/sockets)*clock*(instructions/cycle)
Run Code Online (Sandbox Code Playgroud)

首先,我想找到我的特定算法每个周期的指令数。然后我意识到使用块盒方法几乎不可能计算它,我需要对算法进行深入分析。

但现在,我有两个问题:无论我的机器上运行什么类型的软件及其CPU使用率,有没有办法计算每秒发送到CPU的指令数(每秒百万条指令(MIPS))?是否有可能找到指令集的类型(添加、比较、输入、跳转等)?

任何脚本或工具推荐都将受到赞赏(任何语言)。

cpu performance benchmarking assembly profiling

4
推荐指数
1
解决办法
6058
查看次数