我是否需要在测量性能时防止抢占

Do I need to prevent preemption while measuring performance

我想在 Windows 中使用 QueryPerformanceCounter 来测量代码块的性能。我想知道的是,在不同的 运行s 之间,我是否可以做一些事情来对相同的数据进行相等的测量(我想测量不同排序算法在包含 pod 或一些自定义对象的不同大小的数组上的性能).我知道当前进程可以因为中断或I/O操作而中断执行。我没有做任何 I/O 所以它只是中断可能会影响我的测量,我假设内核也有一些时间框架允许我的进程 运行,所以我认为这会安排把我的 proc 也带走。

人们如何通过测量特定代码段的执行时间来进行准确测量?

刚刚与 Andrei Alexandrescu 一起参加了关于 Fastware 的会议,他正在解决这个确切的问题,即如何测量速度。显然得到平均值是个坏主意但是,多次测量是个好主意。因此,考虑到这一点,您可以测量一百万次并记住最小的测量值,因为实际上这是您获得最少噪音的地方。

方法很糟糕,因为您实际上将更多的噪声权重添加到您测量的实际速度中(这些不是您在评估代码速度时应该考虑的唯一因素,但这是一个好的开始,有关于代码将在何处执行以及代码在一个内核上开始执行并在另一个内核上完成所带来的开销的更可怕的事情,但这是另一回事,我认为它不适用于我的类型)。

一个很好的笑话是:如果你把比尔盖茨放在一辆公共汽车上,那辆公共汽车上的每个人平均都是百万富翁 :))

干杯并感谢所有提供意见的人。

时间测量很棘手,因为您需要找出算法变慢的原因。这取决于输入数据(例如,预分类数据参见 Why is it faster to process a sorted array than an unsorted array?) or the data set size (fits into L1,L2,L3 cache see http://igoro.com/archive/gallery-of-processor-cache-effects/)。

这会对您测量的时间产生巨大影响。 测量顺序也可以起到关键作用。如果您在循环中执行排序日志,并且每个日志都分配了一些内存,那么第一个测试很可能会丢失。不是因为算法较差,而是因为您第一次访问新分配的内存时,它会软故障到您的进程工作集中。释放内存后,堆分配器将 return 池内存,这将具有完全不同的访问性能。如果您对较大(许多 MB)的数组进行排序,这将变得非常明显。

下面是不同线程第一次和第二次打印的2GB数组的触摸次数。每页 (4KB) 内存仅被触及一次。

Threads Size_MB Time_ms us/Page MB/s    Scenario
1       2000    355     0.693   5634    Touch 1
1       2000    11      0.021   N.a.    Touch 2
2       2000    276     0.539   7246    Touch 1
2       2000    12      0.023   N.a.    Touch 2
3       2000    274     0.535   7299    Touch 1
3       2000    13      0.025   N.a.    Touch 2
4       2000    288     0.563   6944    Touch 1
4       2000    11      0.021   N.a.    Touch 2

// Touch is from the compiler point of view a nop operation with no observable side effect 
// This is true from a pure data content point of view but performance wise there is a huge
// difference. Turn optimizations off to prevent the compiler to outsmart us.
#pragma optimize( "", off )
void Program::Touch(void *p, size_t N)
{
    char *pB = (char *)p;
    char tmp;
    for (size_t i = 0; i < N; i += 4096)
    {
        tmp = pB[i];
    }

}
#pragma optimize("", on)

要真正判断算法的性能,仅执行时间测量是不够的,但您需要一个分析器(例如 Windows Performance Toolkit 免费,Intel 的 VTune(不是免费的))以确保您测量了正确的东西,而不是完全不同的东西。