heiheiOo

heiheiOo

0个粉丝

11

问答

0

专栏

0

资料

heiheiOo  发布于  2016-07-23 08:48:14
采纳率 0%
11个问答
4483

请教一下计算函数运行时间的正确方式?

 
用过gettimeofday(),感觉很不靠谱,320*240的图像一千次GMM才30多毫秒……

但是用海思的获取时间戳,1000次要151秒,每帧差不多0.15秒,一秒只能处理5帧……

循环外赋总数变量初值为0,每次循环叠加本次时间差值,程序应该没有问题……

请问一下一般做测试时用什么方式来计算函数运行时间吖?
我来回答
回答10个
时间排序
认可量排序

domenor

0个粉丝

17

问答

0

专栏

1

资料

domenor 2016-07-23 09:19:15
认可0
引出GPIO,函数开始时置高,结束时置低,循环调用函数,使用示波器,观察高电平持续时间,就是函数运行的时间,应该比较精确吧。

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-23 09:36:56
认可0
本帖最后由 ngswfx 于 2016-7-23 10:29 编辑

你是咋调用的呀,这个函数不会这么不靠谱。

虽说不一定精确到1us,但1ms应该不难做到。

//还是建议检查程序,是不是切入点以及变量类型哪里没弄对呀

//你每次把这个时间叠加到YUV数据上?后面的时间算了没有,也很耗时呀,我感觉,你计算的时间和海斯那个得出的时间差异也太大了,感觉不是一回事,仅仅是其中一段。


IV_COM_INF_API unsigned long __stdcall GetTickCount()
{
        struct timeval ts;
        gettimeofday(&ts, NULL);
        return (ts.tv_sec*1000+ts.tv_usec/1000);
}

/////////////////////////////

long lStart=GetTickCount();
long lUseTime=0;
for(int i=0;i<1000;i++){
        long T1=GetTickCount();
        dosomeLongTimeThing();
        long _UsedTime=GetTickCount()-T1;
        ShowUsedTimeOnYUV(_UsedTime);//这部分时间估计没算进去
        lUseTime+=_UsedTime;
}
printf("two time:  %d > %d \n",GetTickCount()-lStart,lUseTime);

////如果在线程里面,随着线程优先级的差异,算出的2个时间差距可能会更大。因为执行中,cpu可能干别的事情去了。

heiheiOo

0个粉丝

11

问答

0

专栏

0

资料

heiheiOo 2016-07-23 09:42:31
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=34667&ptid=12054]ngswfx 发表于 2016-7-23 09:36[/url]
你是咋调用的呀,这个函数不会这么不靠谱。

虽说不一定精确到1us,但1ms应该不难做到。
[/quote]

[code]double totaltime=0.0;               
for(i=0;i<1000;i++)
{
gettimeofday(&starttime, NULL);
                s32Ret = HI_MPI_IVE_GMM(&IveHandle, &(stGmm.stSrc), &(stGmm.stFg), &(stGmm.stBg), &(stGmm.stModel), &(stGmm.stGmmCtrl), bInstant);
                if (s32Ret != HI_SUCCESS)
                {
                        printf("GMM fail,Error(%#x)\n", s32Ret);
                }
                gettimeofday(&endtime, NULL);
                timeuse=1000000 * (endtime.tv_sec - starttime.tv_sec) + endtime.tv_usec - starttime.tv_usec;
totaltime +=timeuse;
}[/code]
大概是这样的……

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-23 09:49:56
认可0
本帖最后由 ngswfx 于 2016-7-23 10:36 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=34669&ptid=12054]heiheiOo 发表于 2016-7-23 09:42[/url]
大概是这样的……[/quote]

哎呀,用了他的函数呀,这里面要分析好多因素的,可以很明确告诉你,这个不一定是阻塞的,或者不是咱们需要的,理解的那种阻塞,从一开始他内部一个值记录开始PTS,干完活了,最后再弄个值PTS。

//这两个pts可不一定发生在这个函数开始以及结束。尤其当系统很忙时,表面上只在忙这个GMM函数,底层可能是把任务下发了(即便有返回,也不见得就是任务的终止),CPU背后还在忙着和GPU交互数据,或者协调其他的事情,比如显示、编解码等等。

//另外这个函数有可能是另外一个核心在干活,他执行的耗时,和你通过pts时间戳得到的时间可能就不是一回事。

你得到的这个时间差,只能做部分参考。尤其是这段代码如果放到了一个线程里面(通常应该是放到线程里面的)。

我感觉你还有一部分耗时内容没算进去。

//建议你在for循环外面再弄个全局变量记录时间,然后,不停累加,这样就可以记录某个函数开始的时间点,然后通过和下一次开始的时间点之差作为执行2次的耗时。这样设计就可以从另外一个层面反映出你系统的劳累程度的。而这样算出来的时间可能会和pts算出来的接近。

//我感觉PTS方法得到时间好比如下:    和你的计算方法可能不一样。
unsigned long nLastPTS=0; //全局
////////////////////////


if(nLastPTS==0)
        nLastPTS=GetTickCount();

////////////////
for(int i=0;i<1000;i++){
        unsigned long nPTS=GetTickCount();
        unsigned long nUsedTime=nPTS-nLastPTS;
        nLastPTS=nPTS;
        printf("usedtime:%lu \n",nUsedTime);
        //////////////////////////////////
        doSomeThingLongtime();
}
///////别的不说,这个gettimeofday,再差也不会偏差几十个ms

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-23 10:40:56
认可0
本帖最后由 ngswfx 于 2016-7-23 10:43 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=34669&ptid=12054]heiheiOo 发表于 2016-7-23 09:42[/url]
大概是这样的……[/quote]

我看了看文档的HI_MPI_IVE_GMM,这就是分配个任务。


用户在创建某个任务后,希望及时得到该任务完成的信息,则需要在创建该任务
时,将 bInstant 设置为 HI_TRUE。否则,如果用户不关心该任务是否完成,建议
将 bInstant 设置为 HI_FALSE,这样可以与后续任务组链执行,减少中断次数,提
升性能。

heiheiOo

0个粉丝

11

问答

0

专栏

0

资料

heiheiOo 2016-07-23 10:42:19
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=34670&ptid=12054]ngswfx 发表于 2016-7-23 09:49[/url]
哎呀,用了他的函数呀,这里面要分析好多因素的,可以很明确告诉你,这个不一定是阻塞的,或者不是咱们 ...[/quote]

不知道为什么我gettimeofday()出来的结果都怪怪的……

然后我刚刚验证了一下海思MPI获取时间戳的方法。

main函数入口和结束相减的结果:
HISIV measuring: 51904868
系统测的整个程序运行时间:
real    0m 51.97s
user    0m 38.79s
sys     0m 1.58s

这个方法还是很贴近的,时间戳单位是微秒(百度百科上我看到写了个毫秒被骗了一晚上……)

但是不太清楚初始化时间戳会有什么作用,应该是我还没有用到那个层面0.0

谢谢前辈指导!

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-23 11:02:18
认可0
本帖最后由 ngswfx 于 2016-7-23 11:11 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=34676&ptid=12054]heiheiOo 发表于 2016-7-23 10:42[/url]
不知道为什么我gettimeofday()出来的结果都怪怪的……

然后我刚刚验证了一下海思MPI获取时间戳的方法 ...[/quote]

你可以在程序执行前,弄个gettimeofday(),结束前再弄个gettimeofday(),2者之差,应该和海思得到的差不多才对。

其实海斯获取时间戳的方法,和gettimeofday()大同小异,底层都会跑到硬件那里去,gettimeofday大家都这么用,不会太差的,关键我的程序,全是这个东西,用的比printf还多,你可别吓我:lol。

//////另外,你一定要把HI_MPI_IVE_GMM最后面的那个参数bInstant,弄成HI_TRUE,否则函数可能直接就返回了(或者部分阻塞,完成必须的某些动作,然后返回了)。不过根据你的描述看,这个函数占用了30个ms,应该已经阻塞了(是不是完全阻塞,不好说,看海思内部实现方法差异了)。

heiheiOo

0个粉丝

11

问答

0

专栏

0

资料

heiheiOo 2016-07-23 13:07:05
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=34677&ptid=12054]ngswfx 发表于 2016-7-23 11:02[/url]
你可以在程序执行前,弄个gettimeofday(),结束前再弄个gettimeofday(),2者之差,应该和海思得到的差 ...[/quote]

0.0这样吖,我都是FALSE

受教了

heiheiOo

0个粉丝

11

问答

0

专栏

0

资料

heiheiOo 2016-07-23 13:15:16
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=34675&ptid=12054]ngswfx 发表于 2016-7-23 10:40[/url]
我看了看文档的HI_MPI_IVE_GMM,这就是分配个任务。


[/quote]

[code]        bInstant = HI_FALSE;
        stDmaCtrl.enMode = IVE_DMA_MODE_DIRECT_COPY;
       
        s32Ret = HI_MPI_IVE_DMA(&IveHandle,&stSrc,&stDst,&stDmaCtrl,bInstant);
        SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, "HI_MPI_IVE_DMA fail,Error(%#x)\n",s32Ret);
       
        //2.Filter
        s32Ret = HI_MPI_IVE_Filter(&IveHandle, &pstGmm->stSrc, &pstGmm->stImg1, &pstGmm->stFltCtrl, bInstant);
        SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, "HI_MPI_IVE_Filter fail,Error(%#x)\n",s32Ret);
       
        //3.Gmm
        s32Ret = HI_MPI_IVE_GMM(&IveHandle, &pstGmm->stImg1, &pstGmm->stFg,&pstGmm->stBg,
        &pstGmm->stModel,&pstGmm->stGmmCtrl, bInstant);
        SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, "HI_MPI_IVE_GMM fail,Error(%#x)\n",s32Ret);
       
        //4.Dilate
        s32Ret = HI_MPI_IVE_Dilate(&IveHandle, &pstGmm->stFg, &pstGmm->stImg1,&pstGmm->stDilateCtrl, bInstant);
        SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, "HI_MPI_IVE_Dilate fail,Error(%#x)\n",s32Ret);
       
        //5.Erode
        s32Ret = HI_MPI_IVE_Erode(&IveHandle, &pstGmm->stImg1, &pstGmm->stImg2,&pstGmm->stErodeCtrl, bInstant);
        SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, "HI_MPI_IVE_Erode fail,Error(%#x)\n",s32Ret);
       
        //6.CCL
        bInstant = HI_TRUE;
        s32Ret = HI_MPI_IVE_CCL(&IveHandle, &pstGmm->stImg2, &pstGmm->stBlob,&pstGmm->stCclCtrl, bInstant);
        SAMPLE_CHECK_EXPR_RET(HI_SUCCESS != s32Ret, s32Ret, "HI_MPI_IVE_CCL fail,Error(%#x)\n",s32Ret);
        s32Ret = HI_MPI_IVE_Query(IveHandle, &bFinish, bBlock);       
        while(HI_ERR_IVE_QUERY_TIMEOUT == s32Ret)
        {
                usleep(100);                                       
                s32Ret = HI_MPI_IVE_Query(IveHandle,&bFinish,bBlock);       
        }

[/code]

其实不太理解HI_FALSE和HI_TRUE的区别,上面是例程里面的一段。在前三个任务中都是false,最后一个任务是true,是因为最后一个了我需要知道整个任务是否完成吗?

然后我刚刚试了一下,将原来的GMM的变成true之后,运行时间少了一半……

我希望得到这个任务的完成信息,时间更快了,这个正常吗?

ngswfx

2个粉丝

55

问答

1

专栏

40

资料

ngswfx 2016-07-24 04:35:08
认可0
本帖最后由 ngswfx 于 2016-7-24 05:21 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=34681&ptid=12054]heiheiOo 发表于 2016-7-23 13:15[/url]
其实不太理解HI_FALSE和HI_TRUE的区别,上面是例程里面的一段。在前三个任务中都是false,最后一个 ...[/quote]

由于有其他任务的存在,应该使用HI_FALSE,这样才能使其他任务顺利执行。

但这不绝对。 主要还是看你的处理前后是否有相关性,这个我IVE我没弄过。

//最后一个是HI_TRUE,也算合理,相当于强制开启处理。是为了配合下面的 HI_MPI_IVE_Query设计的方式,服务的(万一CPU GPU算得快呢)就没必要usleep那个100us了,最起码节约100us。

如果弄成false,我估计也能运行,第一个 HI_MPI_IVE_Query就没有写的必要了。

////////这个IVE我没概念,你多研究一下,多看看文档。
//这些IVE算子距离基础理论有些近了,看得我云里雾里的,超出我的理解范围了,不过DMA接口倒是个好东西,知道物理地址的情况下,拷贝,会节省CPU。

还有HI_MPI_IVE_CSC也不错,用来转换YUV RGB等。这可是GPU在干活,纯硬件实现,效率很高。
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区