我有一个在Linux上运行的C++应用程序,我正在优化它.如何确定代码的哪些区域运行缓慢?
假设我有一些我想以固定顺序执行的语句.我想使用优化级别为2的g ++,因此可以重新排序某些语句.有什么工具可以强制执行某些语句排序?
请考虑以下示例.
using Clock = std::chrono::high_resolution_clock;
auto t1 = Clock::now(); // Statement 1
foo(); // Statement 2
auto t2 = Clock::now(); // Statement 3
auto elapsedTime = t2 - t1;
Run Code Online (Sandbox Code Playgroud)
在这个例子中,重要的是语句1-3以给定的顺序执行.但是,编译器不能认为语句2独立于1和3并执行如下代码?
using Clock=std::chrono::high_resolution_clock;
foo(); // Statement 2
auto t1 = Clock::now(); // Statement 1
auto t2 = Clock::now(); // Statement 3
auto elapsedTime = t2 - t1;
Run Code Online (Sandbox Code Playgroud) 我想为Atmel AVR微控制器编写C代码固件.我将使用GCC编译它.此外,我想启用编译器优化(-Os或-O2),因为我认为没有理由不启用它们,并且它们可能比手动编写汇编更快地生成更好的汇编方式.
但我想要一小段没有优化的代码.我想延迟函数的执行一段时间,因此我想写一个do-nothing循环只是为了浪费一些时间.不需要精确,只需等待一段时间.
/* How to NOT optimize this, while optimizing other code? */
unsigned char i, j;
j = 0;
while(--j) {
i = 0;
while(--i);
}
Run Code Online (Sandbox Code Playgroud)
由于AVR中的内存访问速度要慢得多,因此我希望i并将j其保存在CPU寄存器中.
更新:我刚刚发现UTIL/delay.h和UTIL/delay_basic.h从AVR libc库.尽管大多数情况下使用这些功能可能更好,但这个问题仍然有效且有趣.
相关问题:
我正在用C编写一个小程序,我想测量它的性能.
我想知道它在处理器中运行了多少时间以及它有多少缓存命中+未命中.有关上下文切换和内存使用的信息也很好.
该程序执行时间不到一秒.
我喜欢/ proc/[pid]/stat的信息,但我不知道如何在程序死亡/被杀之后看到它.
有任何想法吗?
编辑:我认为Valgrind增加了很多开销.这就是为什么我想要一个简单的工具,比如/ proc/[pid]/stat,它总是在那里.
performance measurement context-switch cpu-cache memcache-stats
有人可以帮我理解这个: -
(gdb) info frame
Stack level 0, frame at 0xb75f7390:
eip = 0x804877f in base::func() (testing.cpp:16); saved eip 0x804869a
called by frame at 0xb75f73b0
source language c++.
Arglist at 0xb75f7388, args: this=0x0
Locals at 0xb75f7388, Previous frame's sp is 0xb75f7390
Saved registers:
ebp at 0xb75f7388, eip at 0xb75f738c
Run Code Online (Sandbox Code Playgroud)
什么是"ebp,eip Locals at和Previous Frame's sp"是什么意思?请解释
我在SO上看到这篇文章,其中包含C代码以获取最新的CPU周期数:
基于CPU周期计算的C/C++ Linux x86_64中的分析
有没有办法在C++中使用这个代码(欢迎使用windows和linux解决方案)?虽然用C语言编写(而C是C++的一个子集)但我不太确定这段代码是否适用于C++项目,如果没有,如何翻译呢?
我使用的是x86-64
EDIT2:
找到此功能但无法让VS2010识别汇编程序.我需要包含任何内容吗?(我相信我必须换uint64_t到long long窗户......?)
static inline uint64_t get_cycles()
{
uint64_t t;
__asm volatile ("rdtsc" : "=A"(t));
return t;
}
Run Code Online (Sandbox Code Playgroud)
EDIT3:
从上面的代码我得到错误:
"错误C2400:'操作码'中的内联汇编语法错误;找到'数据类型'"
有人可以帮忙吗?
我需要根据x86机器指令数来估计程序中某些热点的确切起始位置(以便稍后可以在某个仿真器/模拟器中运行).有没有办法使用gdb来计算执行到断点的机器指令的数量?
当然还有其他选择,我可以使用仿真/二进制检测工具(如Pin),并在计算指令时跟踪运行,但这需要在我工作的每个平台上安装此工具 - 并非总是可行.我需要一些可以在任何Linux机器上使用的工具.
用GDB,我想它也可以运行stepi X,直到我们遇到断点过大的进步是某种粗粒搜索,然后降低分辨率重复,但是这将是极为缓慢.还有另一种方法吗?
我运行以下调用 perf_event_open 系统调用的程序:Linux sama-desktop 3.18.0-20-rpi2 #21-Ubuntu SMP PREEMPT Sun Apr 5 01:56:02 UTC 2015 armv7l armv7l armv7l GNU/Linux
该程序:
#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, …Run Code Online (Sandbox Code Playgroud) c++ ×3
c ×2
gdb ×2
performance ×2
x86 ×2
arm ×1
avr-gcc ×1
c++11 ×1
cpu-cache ×1
gcc ×1
linux ×1
measurement ×1
optimization ×1
perf ×1
profiling ×1
rdtsc ×1
system-calls ×1
trace ×1
unix ×1