您可以使用哪些技术来分析您的代码

发布于 2024-07-08 15:22:55 字数 107 浏览 7 评论 0原文

我开发的一些平台没有分析工具。 我正在寻找您个人使用过的建议/技术来帮助您识别热点,而无需使用分析器。

目标语言是C++。

我对你个人使用过的东西很感兴趣。

Some of the platforms that I develop on, don't have profiling tools. I am looking for suggestions/techniques that you have personally used to help you identify hotspots, without the use of a profiler.

The target language is C++.

I am interested in what you have personally used.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

杯别 2024-07-15 15:22:55

不是开玩笑:除了将计时转储到 std::cout 和其他面向文本/数据的方法之外,我还使用 Beep() 函数。 听到两个“嘟嘟”检查点之间的寂静间隙会给人一种不同的印象。

这就像看书面乐谱和实际听到乐谱之间的区别。 这就像读取 rgb(255,0,0) 和看到消防车红色之间的区别。

所以,现在,我有一个客户端/服务器应用程序,并具有不同频率的蜂鸣声,标记客户端发送消息的位置、服务器开始回复的位置、完成回复的位置、回复首先进入客户端的位置等,我可以非常自然而然地就能感觉到时间都花在哪里了。

No joke: In addition to dumping timings to std::cout and other text/data oriented approaches I also use the Beep() function. There's something about hearing the gap of silence between two "Beep" checkpoints that makes a different kind of impression.

It's like the difference between looking at a written sheet music, and actually HEARING the music. It's like the difference between reading rgb(255,0,0) and seeing fire-engine red.

So, right now, I have a client/server app and with Beeps of different frequencies, marking where the client sends the message, where the server starts its reply, finishes its reply, where reply first enters the client, etc, I can very naturally get a feel for where the time is spent.

握住你手 2024-07-15 15:22:55

我发现以下内容非常有用:

#ifdef PROFILING
# define PROFILE_CALL(x) do{ \
    const DWORD t1 = timeGetTime(); \
    x; \
    const DWORD t2 = timeGetTime(); \
    std::cout << "Call to '" << #x << "' took " << (t2 - t1) << " ms.\n"; \
  }while(false)
#else
# define PROFILE_CALL(x) x
#endif

可以在调用函数中使用:

PROFILE_CALL(renderSlow(world));
int r = 0;
PROFILE_CALL(r = readPacketSize());

I've found the following quite useful:

#ifdef PROFILING
# define PROFILE_CALL(x) do{ \
    const DWORD t1 = timeGetTime(); \
    x; \
    const DWORD t2 = timeGetTime(); \
    std::cout << "Call to '" << #x << "' took " << (t2 - t1) << " ms.\n"; \
  }while(false)
#else
# define PROFILE_CALL(x) x
#endif

Which can be used in the calling function as such:

PROFILE_CALL(renderSlow(world));
int r = 0;
PROFILE_CALL(r = readPacketSize());
肤浅与狂妄 2024-07-15 15:22:55

本质上,如果分析工具不可用,您就可以模拟分析器会执行的操作。 您将计数器插入到您认为有趣的函数中,并计算它们被调用的次数以及可能使用的参数大小/类型。

如果您可以访问平台上的任何计时器,则可以在所述函数的开始/结束处启动/停止这些计时器,以获取执行时间信息(如果代码中不清楚)。 这将为您在复杂的代码中带来最大的收益,因为通常会有太多的函数来检测它们。 相反,您可以通过为每个代码段指定一个专用计时器来获取在某些代码段中花费的时间。

这两种技术结合起来可以形成一种迭代方法,您可以使用计时器找到消耗大部分周期的大部分代码,然后以更细的粒度检测各个函数以解决问题。

In essence, if a profiling tool is not available, you emulate what a profiler would have done. You insert counters into functions you think are interesting and count how many times, and potentially with what size/sort of arguments they're called.

If you have access to any timers on your platform, you may start/stop these at the beginning/end of said functions to get execution time information as well, if this is unclear from the code. This is going to give you the biggest bang for your buck in complex code, as there will usually be too many functions to instrument them all. Instead, you can obtain the time spent in certain sections of code by dedicating a timer to each one.

These two techniques in tandem can form an iterative approach, where you find the broad section of code that consumes the majority of your cycles using timers, then instrument individual functions at a finer granularity to hone in on the problem.

孤檠 2024-07-15 15:22:55

如果持续时间足够长(例如一分钟或更长时间),我会在调试器中运行软件,然后中断几次并查看调试器在哪里中断,这可以非常粗略地了解软件的功能(例如如果你打破 10 次并且它们都在同一个地方,这会告诉你一些有趣的事情!)。
非常粗糙且准备就绪,但不需要任何工具、仪器等。

If it is something sufficiently long in duration (e.g. a minute or more), I run the software in a debugger then break a few times and see where the debugger breaks, this gives a very rough idea of what the software is up to (e.g. if you break 10 times and they are all in the same place, this tells you something interesting!).
Very rough and ready but doesn't require any tools, instrumentation etc.

空‖城人不在 2024-07-15 15:22:55

我不确定您想要什么平台,但在嵌入式微控制器上,有时调整备用数字输出线并使用示波器、计数器/定时器或逻辑分析仪测量脉冲宽度会很有帮助。

I'm not sure what platforms you had in mind, but on embedded microcontrollers, it's sometimes helpful to twiddle a spare digital output line and measure the pulse width using an oscilloscope, counter/timer, or logic analyzer.

ゞ花落谁相伴 2024-07-15 15:22:55

我会使用 80/20 规则,并在热点或有趣的调用路径周围放置计时器。 您应该大致了解瓶颈所在(或至少大部分执行路径),并使用适当的依赖于平台的高分辨率计时器(QueryPerformanceCounters、gettimeofday 等)。

我通常不会在启动或关闭时打扰任何事情(除非需要),并且会有明确定义的“瓶颈”,通常是消息传递或某种算法计算。 我通常发现消息接收器/src(更重要的是接收器)、队列、互斥体以及简单的混乱(算法、循环)通常会导致执行路径中的大部分延迟。

I would use the 80/20 rule and put timers around hotspots or interesting call paths. You should have a general idea where the bottlenecks will be (or at least a majority of the execution paths) and use the appropriate platform dependent high resolution timer (QueryPerformanceCounters, gettimeofday, etc.).

I usually don't bother with anything at startup or shutdown (unless needed) and will have well defined "choke points", usually message passing or some sort of algorithmic calculation. I've generally found that message sinks/srcs (sinks moreso), queues, mutexes, and just plain mess-ups (algorithms, loops) usually account for most of the latency in an execution path.

木緿 2024-07-15 15:22:55

您使用的是 Visual Studio 吗?

您可以使用 /Gh 和 /GH 开关。 这是一个涉及堆栈检查的示例

这些标志允许您通过文件- 文件基础,注册每次在运行时输入和/或离开方法时调用的未修饰函数。

然后,您可以注册所有时间的分析信息,而不仅仅是计时信息。 堆栈转储、调用地址、返回地址等。这很重要,因为您可能想知道“函数 X 在函数 Z 下使用了 Y 时间”,而不仅仅是函数 X 所花费的总时间。

Are you using Visual Studio?

The you can use the /Gh and /GH switches. Here's an example involving stack inspection

These flags allow you, by a file-by-file basis, to register undecorated functions that are called every time a method is entered and/or left in runtime.

You can then register all times of profiling information, not just timing information. Stack-dumps, calling address, return address, etc. Which is important, because you may want to know that 'function X used Y time under function Z' and not just the total time spent in function X.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文