在Windows中测试c语言单个函数运行时间方法

本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!前端

在作单片机项目开发的过程当中,在特殊应用中对代码执行的时间有着严格的要求,那么如何准确的测试出每一个函数的的运行速度是多快呢?一般用单片机测试的方法就是经过示波器观察。ios

好比如今要测试使用二分查找法,在数组中查找一个数字须要屡次时间,测试方法为:每运行一次查找算法,就让LED引脚电平翻转一次,而后使用示波器观察LED引脚的波形,大概就能测试出这个算法的执行时间了。算法

测试代码以下:后端

#include "iostm8s103F3.h"
#include "led.h"
#include "find.h"

void sysclkinit( void ) {
    CLK_SWR = 0xe1;       //HSI为主时钟源 16MHz CPU时钟频率
    CLK_CKDIVR = 0x00;    //CPU时钟0分频,系统时钟0分频
}

void main( void ) {
    sysclkinit();		          //时钟初始化
    __asm( "sim" );                       //禁止中断
    led_init();
    __asm( "rim" );                       //开启中断
    while( 1 )
    {   
        LED = !LED;         
        val = binary_search( ( int* )volref, 500, 0, sizeof( volref ) / sizeof( volref[0] ) );   
    }
}
复制代码

binary_search为二分查找法函数,在100个数据的数组中查找数字500是否存在,LED每翻转一次,执行一次函数。而后经过示波器观察LED的波形。数组

image.png

能够看到LED引脚的高低电平时间都为164us,说明这个二分查找法查找数字500所用的时候为164us。LED引脚自己的翻转速度小于0.1us,因此LED引脚翻转自己使用的时间在这里能够忽略不计。markdown

这样在单片机中能够经过LED引脚的翻转经过示波器来观察要测试的函数具体执行所占用的时间。app

这样测试积极精确,可是也比较麻烦,每次测试的时候,还必需要经过硬件电路才能测试,那么能不能不用硬件电路,直接经过软件测试呢?方法固然是有的,能够在Windows中在C编译器中经过软件仿真,测试每一个函数执行的时间。ide

这里使用的编译器为 Dev-C++,这个编译器里面能够直接运行单片机中写好的C函数,而后经过系统提供个几个时间函数,就能够准确测试出函数运行时间了。函数

image.png

系统提供的能够测试函数有下面几个post

  1. clock()函数

The clock() function returns an approximation of processor time used by the program.

The value returned is the CPU time used so far as a clock_t; to get the number of seconds used, divide byCLOCKS_PER_SEC. If the processor time used is not available or its value cannot be represented, the functionreturns the value (clock_t) -1.

简单而言,就是该程序从启动到函数调用占用CPU的时间。这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数。

函数原型以下:

image.png

返回值类型为clock_t,实际上是一个长整形。

image.png

调用这个函数的时候,会返回一个CPU当前时间计数值。要测试时间的话,在函数以前前调用一次clock()函数,将当前时间计数值存储起来。而后调用要测试的函数,测试函数结束以后,在调用一次clock()函数,读取当前的时间计数值,而后用这个计数值减去函数执行前的时间计数值,就能够计算出来函数执行所用的时间,这个时间单位默认为ms。

2.GetTickCount()函数

GetTickCount返回(retrieve)从操做系统启动所通过(elapsed)的毫秒数,它的返回值是DWORD,也是一个长整型数。

它的用法和clock()函数基本同样,在函数执行前调用一次GetTickCount()函数,而后执行函数,函数执行完成后再调用一次GetTickCount()函数,而后计算两次测时间差,这个单位也是ms。

在Windows系统中感受ms很短,可是对于单片机来讲ms时间仍是比较长的,好多函数的执行时间远远小于1ms,若是用上面这两种方法测试的话,许多函数的执行时间是测试不出来的。那么就须要使用更高精度的测试函数。

  1. QueryPerformanceCounter()函数

调用这个函数会返回硬件支持的高精度计数器的频率。注意这个返回的是系统的计时器值,不是时间值。上面两个函数返回的是系统的时间值,而这个函数返回的是系统的计数器值,这个计数器的值至关于时间值来讲,精度就高不少了,大多数的精度均可以达到us级。

这个函数在使用前首先要调用QueryPerformanceFrequency()函数获取系统的计数频率,也就是1s钟系统会计数多少次。

而后使用QueryPerformanceCounter()获取在程序运行先后的计数器值,而后用两次计数器值的差除以计数的频率,就能计算出函数执行所使用的时间。

下面开始使用Dev C++软件测试这三种函数。

编写测试代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

//待测试函数 
void fun(void) {
	sleep(1);
}
typedef union _LARGE_INTEGER {
	struct {
		long LowPart ;// 4字节整型数
		long  HighPart;// 4字节整型数
	};
	long long QuadPart;// 8字节整型数

} LARGE_INTEGER;

int main(int argc, char *argv[]) {
	int i = 0,val = 0;
	clock_t startTime,endTime;
	int time = 0;
	
	// 方法 1
	startTime = clock();			//计时开始
	fun();					//调用函数 
	endTime = clock();			//计时结束
	printf(" 1:程序运行时间为: %d ms\r\n\r\n\r\n",(endTime - startTime));

	//方法 2
	startTime = GetTickCount();		//计时开始
	fun();					//调用函数 
	endTime = GetTickCount();		//计时结束
	printf(" 2:程序运行时间为: %d ms\r\n\r\n\r\n",(endTime - startTime));

	//方法 3
	LARGE_INTEGER secondcount= {0};
	LARGE_INTEGER startcount= {0};
	LARGE_INTEGER stopcount= {0};

	QueryPerformanceFrequency(&secondcount);     //获取每秒多少CPU Performance Tick 单位us 
	printf(" 3:系统计数频率为: %d \r\n",secondcount.QuadPart);

	QueryPerformanceCounter(&startcount);		//计时开始
	fun();						//调用函数 
	QueryPerformanceCounter(&stopcount);		//计时结束
	
	time=( ((stopcount.QuadPart - startcount.QuadPart)*1000*1000)/secondcount.QuadPart);
	printf(" 程序运行时间为: %d us\r\n\r\n",time);

	system("pause");
	return 0;
}

复制代码

image.png

运行结果以下

image.png

这里的测试函数实际为 sleep(1); 也就是休眠1s钟,而后使用3种方法分别测试函数执行时间。

使用clock()函数测试代码执行时间为1000ms,使用GetTickCount()函数测试代码执行时间为998ms,使用QueryPerformanceCounter()函数测试代码执行时间为999630us,也就是999.63ms。经过QueryPerformanceFrequency()函数读取到系统1s钟的计数次数为2630703次。

经过系统自带的时间函数就能够直接测试每一个函数执行的时间,这样就能够不使用硬件电路,就能够直接对比不一样的函数执行效率了。

相关文章
相关标签/搜索