【发布时间】:2017-09-20 15:08:58
【问题描述】:
我已经搜索并使用了许多方法来测量经过的时间。为此目的有很多问题。例如,this 问题非常好,但是当您需要准确的时间记录器时,我找不到好的方法。为此,我想在这里分享我的方法,以供使用并在有问题时予以纠正。
更新&注意:这个问题是针对基准测试的,不到一纳秒。这与使用clock_gettime(CLOCK_MONOTONIC,&start); 完全不同,它记录的时间超过一纳秒。
更新:衡量加速的一种常用方法是重复程序中应该进行基准测试的部分。但是,正如评论中提到的,当研究人员依赖自动矢量化时,它可能会显示出不同的优化。
注意 在一次重复中测量经过的时间不够准确。在某些情况下,我的结果表明该部分必须重复超过 1K 或 1M 才能获得最短时间。
建议:我不熟悉 shell 编程(只知道一些基本命令...)但是,可以测量最小时间而无需在程序内部重复。 p>
我当前的解决方案为了防止出现分支,我使用宏 #define REP_CODE(X) X X X... X X 重复 ode 部分,其中 X 是我要进行基准测试的代码部分,如下所示:
//numbers
#define FMAX1 MAX1*MAX1
#define COEFF 8
int __attribute__(( aligned(32))) input[FMAX1+COEFF]; //= {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
int __attribute__(( aligned(32))) output[FMAX1];
int __attribute__(( aligned(32))) coeff[COEFF] = {1,2,3,4,5,6,7,8};//= {1,1,1,1,1,1,1,1};//; //= {1,2,1,2,1,2,1,2,2,1};
int main()
{
REP_CODE(
t1_rdtsc=_rdtsc();
//Code
for(i = 0; i < FMAX1; i++){
for(j = 0; j < COEFF; j++){//IACA_START
output[i] += coeff[j] * input[i+j];
}//IACA_END
}
t2_rdtsc=_rdtsc();
ttotal_rdtsc[ii++]=t2_rdtsc-t1_rdtsc;
)
// The smallest element in `ttotal_rdtsc` is the answer
}
这不影响优化,但在某些情况下还受到代码大小和编译时间过多的限制。
有什么建议和更正吗?
提前致谢。
【问题讨论】:
-
“这个问题是针对基准测试的,不到一纳秒。”,为什么,
-
@rubenvb,你是对的。但是,两者都需要。如果您正在努力优化一个真实的应用程序,那很好。
-
如果没有专用的计时硬件,您根本无法以如此小的间隔准确测量时间。
rdtsc对此不可靠。如果您想对快速操作进行基准测试,请像其他 10,000 次基准测试一样:运行该操作数千或数百万次,然后除以迭代次数。这不是火箭科学。 -
@FackedDeveloper,简单的 rdtsc 无法准确测量 3-4 条指令(它们在 3-4 GHz CPU 上总共为 1 纳秒),因为有:命令的乱序执行(并且 rdtsc 没有序列化,并且序列化 > 10 滴答声)和长 CPU 流水线(> 12 个阶段,或 > 3-4 ns)。只有“简单”的时间来执行某些命令是不可能的,您不应该比较编译器,而是比较具有良好微体系结构知识的编译器生成的机器代码,使用模拟器(intel IACA)和性能计数器(pmu-tools - ocperf .py)。
-
是的,平均运行 1000 次迭代(针对实际工作负载)是最好的。
标签: c performance x86 intrinsics