【发布时间】:2017-08-18 21:09:00
【问题描述】:
我正在编写一个函数,用于获取调用特定 void (*)(void) aka void -> void 函数特定次数所需的时钟平均值。
我担心如果样本量太大,观察的总和会溢出,使平均值无效。
有没有一种标准方法可以消除这类问题中总和溢出的可能性?
注意:我知道这个例子太天真了,无法得出任何关于性能的结论;我有兴趣消除总和溢出的可能性,而不是在性能方面做出任何结论。
注 2:我也知道除非程序运行数百年,否则 64 位无符号数实际上不会溢出,但我很好奇是否也可以消除这个假设。
这是我的独立代码:
#include <Windows.h>
#include <stdio.h>
/**
* i want to parametrize the type which is used to store sample size
* to see whether it impacts performance
*/
template <typename sampleunit_t>
static inline ULONGLONG AveragePerformanceClocks (void (*f)(), sampleunit_t nSamples)
{
ULONGLONG sum;
sampleunit_t i;
sum = 0;
for (i = 0; i < nSamples; ++i) {
LARGE_INTEGER t1;
LARGE_INTEGER t2;
ULONGLONG dt;
QueryPerformanceCounter(&t1);
f();
QueryPerformanceCounter(&t2);
dt = t2.QuadPart - t1.QuadPart;
// sum may possibly overflow if program runs long enough with
// a large enough nSamples
sum += dt;
}
return (ULONGLONG)(sum / nSamples);
}
/* a cdecl callback that consumes time */
static void test1()
{
// don't optimize
volatile int i;
for (i = 0; i < 10000; ++i) {
}
}
int main(int argc, char **argv)
{
ULONGLONG avg;
avg = AveragePerformanceClocks<BYTE>(test1, 255);
printf("average clocks(truncated): %llu.\n", avg);
avg = AveragePerformanceClocks<WORD>(test1, 255);
printf("average clocks(truncated): %llu.\n", avg);
avg = AveragePerformanceClocks<DWORD>(test1, 255);
printf("average clocks(truncated): %llu.\n", avg);
avg = AveragePerformanceClocks<ULONGLONG>(test1, 255);
printf("average clocks(truncated): %llu.\n", avg);
system("pause");
return 0;
}
【问题讨论】:
-
您的计算已关闭。如果函数运行数十万年,该值只会实际溢出。这不是一个值得担心的问题。如果您通常担心整数溢出,您应该问这个问题。它也会缩短minimal reproducible example。