8 c++ performance profiling timer
在SO上,有很多关于性能分析的问题,但我似乎没有找到整体情况.涉及到相当多的问题,大多数问答都会忽略所有问题,但不能忽视其中的一些问题.
我想知道什么.如果我有两个功能做同样的事情,我很好奇速度的差异,没有外部工具,定时器测试这个是否有意义,或者在测试中编译会影响结果吗?
我问这个是因为如果它是明智的,作为一个C++程序员,我想知道它应该如何做到最好,因为它们比使用外部工具简单得多.如果它有意义,让我们继续讨论所有可能的陷阱:
考虑这个例子.以下代码显示了执行相同操作的两种方法:
#include <algorithm>
#include <ctime>
#include <iostream>
typedef unsigned char byte;
inline
void
swapBytes( void* in, size_t n )
{
for( size_t lo=0, hi=n-1; hi>lo; ++lo, --hi )
in[lo] ^= in[hi]
, in[hi] ^= in[lo]
, in[lo] ^= in[hi] ;
}
int
main()
{
byte arr[9] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' };
const int iterations = 100000000;
clock_t begin = clock();
for( int i=iterations; i!=0; --i )
swapBytes( arr, 8 );
clock_t middle = clock();
for( int i=iterations; i!=0; --i )
std::reverse( arr, arr+8 );
clock_t end = clock();
double secSwap = (double) ( middle-begin ) / CLOCKS_PER_SEC;
double secReve = (double) ( end-middle ) / CLOCKS_PER_SEC;
std::cout << "swapBytes, for: " << iterations << " times takes: " << middle-begin
<< " clock ticks, which is: " << secSwap << "sec." << std::endl;
std::cout << "std::reverse, for: " << iterations << " times takes: " << end-middle
<< " clock ticks, which is: " << secReve << "sec." << std::endl;
std::cin.get();
return 0;
}
// Output:
// Release:
// swapBytes, for: 100000000 times takes: 3000 clock ticks, which is: 3sec.
// std::reverse, for: 100000000 times takes: 1437 clock ticks, which is: 1.437sec.
// Debug:
// swapBytes, for: 10000000 times takes: 1781 clock ticks, which is: 1.781sec.
// std::reverse, for: 10000000 times takes: 12781 clock ticks, which is: 12.781sec.
Run Code Online (Sandbox Code Playgroud)
问题:
沉思:
似乎提出了两个高精度计时器:clock()和QueryPerformanceCounter(在windows上).显然我们想测量代码的cpu时间而不是实时,但据我所知,这些函数没有提供该功能,因此系统上的其他进程会干扰测量.gnu c库上的这个页面似乎与此相矛盾,但是当我在vc ++中放置一个断点时,调试过程会获得大量的时钟滴答,即使它被挂起(我还没有在gnu下测试过).我是否遗漏了替代计数器,或者我们是否至少需要特殊的库或类?如果没有,在这个例子中时钟是否足够好或者是否有理由使用QueryPerformanceCounter?
没有调试,反汇编和分析工具,我们可以确定什么?有什么事实发生吗?函数调用是否内联?在检查调试器时,字节实际上是交换的,但我宁愿从理论上知道为什么,而不是从测试.
谢谢你的任何指示.
更新
由于来自tojas的提示,swapBytes函数现在运行速度与std :: reverse一样快.我没有意识到在一个字节的情况下临时副本必须只是一个寄存器,因此非常快.优雅可以使你失明.
inline
void
swapBytes( byte* in, size_t n )
{
byte t;
for( int i=0; i<7-i; ++i )
{
t = in[i];
in[i] = in[7-i];
in[7-i] = t;
}
}
Run Code Online (Sandbox Code Playgroud)
感谢ChrisW的一个提示,我发现在Windows上你可以通过Windows Management Instrumentation获得(读取:你的)进程所消耗的实际cpu时间.这绝对看起来比高精度计数器更有趣.
显然,我们想测量我们代码的 CPU 时间而不是实时时间,但据我所知,这些函数没有提供该功能,因此系统上的其他进程会干扰测量。
我做了两件事,以确保挂钟时间和 CPU 时间大致相同:
测试相当长的时间,即几秒钟(例如,通过测试数千次迭代的循环)
在机器或多或少相对空闲时进行测试,除了我正在测试的任何内容。
或者,如果您只想/更准确地测量每个线程的 CPU 时间,则可以将其用作性能计数器(参见例如perfmon.exe
)。
如果没有调试、反汇编和分析工具,我们能确定什么?
几乎没有(除了 I/O 往往相对较慢)。
归档时间: |
|
查看次数: |
7255 次 |
最近记录: |