免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: huihuiqi
打印 上一主题 下一主题

在C里面如何将程序执行时间精确到毫秒或者更加精确!! [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-07-10 13:58 |只看该作者
原帖由 huihuiqi 于 2009-7-10 11:42 发表
C语言中,我想测试两个算法的执行时间,看看哪个更快,但是调用系统时间函数都只能精确到秒,看不出差别,有没有哪位大侠知道怎样才能把程序执行时间精确到毫秒或者更加精确?急,谢谢!!

最好有现成可以直 ...


现成代码~~~~唔~~~~~
参考这个
http://libasdl.svn.sourceforge.n ... _02.cpp?view=markup
或者这个
http://libasdl.svn.sourceforge.n ... _03.cpp?view=markup
吧,但我直接用的是ticks,当时偷懒没有换算成毫秒或者微妙。
gettimeday 和 rdtsc Windows也是可以用的。

不过VC 6嘛,试一下吧,因为VC 6自带的SDK已经很老很老了……

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
12 [报告]
发表于 2009-07-10 14:05 |只看该作者

回复 #10 huihuiqi 的帖子

LARGE_INTEGER c1=LARGE_INTEGER() , c2=LARGE_INTEGER();
QueryPerformanceCounter(&c1);
// 被测试的代码
QueryPerformanceCounter(&c2);

std::cout<<"use "<<c2.QuadPart-c1.QuadPart<<" ticks\n";

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
13 [报告]
发表于 2009-07-10 14:14 |只看该作者

回复 #11 swxlion 的帖子

我也觉得直接算tick比较好……

vc6很幸运的有这这个函数,也有LARGE_INTEGER的定义,不过没看懂……

#if defined(MIDL_PASS)
typedef struct _LARGE_INTEGER {
#else // MIDL_PASS
typedef union _LARGE_INTEGER {
    struct {
        DWORD LowPart;
        LONG HighPart;
    };  /** 这里是为什么……  不是和下面重复了么…… */
    struct {
        DWORD LowPart;
        LONG HighPart;
    } u;
#endif //MIDL_PASS
    LONGLONG QuadPart;
} LARGE_INTEGER;

论坛徽章:
0
14 [报告]
发表于 2009-07-10 14:29 |只看该作者

回复 #9 OwnWaterloo 的帖子

原帖由 OwnWaterloo 于 2009-7-10 13:17 发表
关于这个, 如果有了高精度的计时器(比如已经精确到cpu tick), 是否反而应该测量只跑一次的结果?
测量跑多次的总时间会受调度方面的影响。

“测量多次,每次只跑一次,取多次结果中的最小值”, 也不是我想到的……  云风说的……


这个是否只测一次,我觉得还应该看具体的被测对象决定。如果是很短的操作,比如除法或者加法,或者发给硬件的单条指令,我觉得反复重复多次单次测量,然后去掉那些偏离较大的样本值,这样能求出一个一般状态下的统计平均值。
但如果是稍微复杂一点的算法,那么在单次测试时,如果算法开始执行的时候,已经到了时间片的末期,那这个算法也很可能会受到任务切换的影响。这个是我实际测试的总结。如果算法足够复杂,那可能会在一次执行时就遇到多次的任务切换,或者是在系统压力较大的时候,虽只切换一次,但排队时间很长,导致时间的拉大。有些时候,刚好遇上新切入的高优先级的任务刚好有内存数据需要换入换出。

因此我觉得,如果要单次测量的话,那最好指定进程/线程为最高优先级,且最好不可被抢占(内核中)。
然后风云说的话,我不太同意。因为多次结果中的最小值没有普适的意义。它只代表了一个理想状态下的最高峰值,而不是实际运行中的常态均值。
而且对某些操作,可能反而达不到效果。比如一个取值操作,正常的需求是从内存中取到,然而如果性能测试用例不当,当多次测试后,该值将不会再从内存中获取,而是从CPU cache或者寄存器中获取。所以如果测试逻辑不严密,最小值也不一定是实际数值。

[ 本帖最后由 swxlion 于 2009-7-10 14:31 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2009-07-10 14:35 |只看该作者
#include <stdio.h>
#include <windows.h>

void main()
{
LARGE_INTEGER t0, t1, f;

QueryPerformanceFrequency(&f);

QueryPerformanceCounter(&t0);

Sleep(1000);

QueryPerformanceCounter(&t1);

printf("%f\n", (double)(t1.QuadPart - t0.QuadPart) / f.QuadPart);
}

上面这段代码执行时没有错误~

当我把它加入到我自己的程序里时出错:
error C2059: syntax error : 'constant'
winnt.h(5441) : error C2238: unexpected token(s) preceding ';'
syntax error : found 'int (' at global scope (was a declaration intended?)
type 'int' unexpected
error C2059: syntax error : ')'
error C2065: 't1' : undeclared identifier
error C2228: left of '.QuadPart' must have class/struct/union type
error C2065: 't0' : undeclared identifier
error C2228: left of '.QuadPart' must have class/struct/union type
error C2065: 'f' : undeclared identifier
error C2228: left of '.QuadPart' must have class/struct/union type
syntax error : found 'int (' at global scope (was a declaration intended?)
error C2062: type 'int' unexpected
error C2059: syntax error : ')'
error C2143: syntax error : missing ';' before '{'
error C2447: missing function header (old-style formal list?)
执行 cl.exe 时出错.

1 error(s), 0 warning(s)

论坛徽章:
0
16 [报告]
发表于 2009-07-10 14:37 |只看该作者
原帖由 OwnWaterloo 于 2009-7-10 14:14 发表
我也觉得直接算tick比较好……

vc6很幸运的有这这个函数,也有LARGE_INTEGER的定义,不过没看懂……

#if defined(MIDL_PASS)
typedef struct _LARGE_INTEGER {
#else // MIDL_PASS
typedef union _LARGE_INTEGER {
    struct {
        DWORD LowPart;
        LONG HighPart;
    };  /** 这里是为什么……  不是和下面重复了么…… */
    struct {
        DWORD LowPart;
        LONG HighPart;
    } u;
#endif //MIDL_PASS
    LONGLONG QuadPart;
} LARGE_INTEGER;


哈哈,回帖的时候被人叫走,结果回完的时候发现你已经回了两楼了。哈哈

这个一开始我也没明白,但后面见有这么用的:
LARGE_INTEGER  li;
li.LowPart = li.u.LowPart;
估计是命名成员和匿名成员的关系。不过我没有深究……

[ 本帖最后由 swxlion 于 2009-7-10 14:39 编辑 ]

论坛徽章:
0
17 [报告]
发表于 2009-07-10 14:48 |只看该作者

回复 #15 huihuiqi 的帖子

VS2008正常,我这没有vc 6,只能找别人帮你看一下了。
怀疑是平台的宏定义问题。比如WINNT之类的……

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
18 [报告]
发表于 2009-07-10 15:09 |只看该作者

回复 #17 swxlion 的帖子

我用vc6测了  也没有问题……    不明白了……

论坛徽章:
0
19 [报告]
发表于 2009-07-10 15:15 |只看该作者
windows上有gettickcount可以算到ms吧

论坛徽章:
0
20 [报告]
发表于 2009-07-10 16:32 |只看该作者
原帖由 swxlion 于 2009-7-10 14:48 发表
VS2008正常,我这没有vc 6,只能找别人帮你看一下了。
怀疑是平台的宏定义问题。比如WINNT之类的……


嗯,已经解决了!
就是和宏定义有关:加了#include <windows.h>之后和我的max函数产生了冲突。
谢谢楼上各位,你们的意见都很有效!
:wink:
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP