coremark & dhrystone 移植要点

移植coremark & dhrystone要点

1. coremark

1.1 coremark 计算方法

​ 计算的核心为下方的代码

    start_time();
#if (MULTITHREAD > 1)
/* 多线程的情况 */
#else
/*单线程情况*/
    iterate(&results[0]);
#endif
    stop_time();

​ 对于 iterate(&results[0]); 再追进去可以发现

void * iterate(void *pres)
{
    ee_u32        i;
    ee_u16        crc;
    core_results *res        = (core_results *)pres;
    ee_u32        iterations = res->iterations;
    res->crc                 = 0;
    res->crclist             = 0;
    res->crcmatrix           = 0;
    res->crcstate            = 0;

    for (i = 0; i < iterations; i++)
    {
        crc      = core_bench_list(res, 1);
        res->crc = crcu16(crc, res->crc);
        crc      = core_bench_list(res, -1);
        res->crc = crcu16(crc, res->crc);
        if (i == 0)
            res->crclist = res->crc;
    }
    return NULL;
}

​ 而这里的iterations 会在results[0].iterations = get_seed_32(4);函数中被赋值为ITERATIONS,所以我们可以知道,其实coremark 就是获取了下面这些参数

  • start_time();
  • stop_time();
  • iterations

​ 然后通过下面的代码算出 循环次数÷时间 的结果,可以看下面的代码,用default_num_contexts * results[0].iterations / time_in_secs(total_time)计算出了目标值。

​ 但是实际我们看的分数是Iterations/Sec /MHZ,即最后需要的结果是跑分/(你的时钟/1MHZ),例如我最后跑分是14,频率是5MHZ,那么我的实际结果是:14/(5/1) = 2.8 coremark/Mhz

    /* and report results */
    ee_printf("CoreMark Size    : %lu\n", (long unsigned)results[0].size);
    ee_printf("Total ticks      : %lu\n", (long unsigned)total_time);
#if HAS_FLOAT
	/* 有浮点的情况 */
#else
    ee_printf("Total time (secs): %d\n", time_in_secs(total_time));
    if (time_in_secs(total_time) > 0)
        ee_printf("Iterations/Sec   : %d\n",
                  default_num_contexts * results[0].iterations
                      / time_in_secs(total_time));
#endif
    if (time_in_secs(total_time) < 10)
    {
        ee_printf(
            "ERROR! Must execute for at least 10 secs for a valid result!\n");
        total_errors++;
    }
    ee_printf("Iterations       : %lu\n",
              (long unsigned)default_num_contexts * results[0].iterations);
    ee_printf("Compiler version : %s\n", COMPILER_VERSION);
    ee_printf("Compiler flags   : %s\n", COMPILER_FLAGS);

1.2 coremark 移植方法

由1.1 我们就可以知道,其实coremark 就是跑个程序n 循环,然后计算一个 指令/时间/频率 这样的结果,所以我们移植只需要给出以下几个参数

  • 时间获取方式,start_time() 和 stop_time()向里追,最后会有时间函数的实现,这里一般获取的都是cnt 数,需要结合自己的硬件定时器来实现这个函数,这里只是获取了计数值,没有考虑时钟频率的影响。

  • CLOCKS_PER_SEC 这个宏定义改为你的时钟频率,第一点的获取了这段时间内增加的cnt值,这里有了时间周期,那么time_in_secs(total_time)这个函数就能够计算出执行当前的时间了。其实最后也是cnt 值/频率=时间

  • iterations ,结合时钟频率不同,需要保证coremark 跑10s 以上,即time_in_secs(total_time)计算出来的结果是10s 以上,按照实际的结果给一个值就可以了。

  • printf 的实现,需要根据实际情况注意是不是要加printf这个宏

    //如果编译的时候加上了  -DHAS_PRINTF,那么这里就不会生效,但是还是代表了HAS_PRINTF
    #ifndef HAS_PRINTF
    #define HAS_PRINTF 1
    #endif
    
    //由于coremark 都是使用的ee_printf,所以需要把ee_printf符号替换为printf
    #if HAS_PRINTF
    #define ee_printf printf
    #endif
    

    以上就是移植的要点,需要哪些文件内容官网readme 有说,就不赘述了。

2. dhrystone

2.1 dhrystone 计算方式

​ 和coremark 类似,dhrystone的主函数也是进行算 跑dhrystone 程序的时间,以推出来单位时间下跑dhrystone 的个数,再除以MHZ的话就可以推出来 再1MHZ的情况下,1秒能跑多少dhrystone 程序。

​ 主题程序如下:

  /***************/
  /* Start timer */
  /***************/
#ifdef TIMES
  times (&time_info);
  Begin_Time = (long) time_info.tms_utime;
#endif
#ifdef TIME
  Begin_Time = time ( (long *) 0);
#endif
#ifdef MSC_CLOCK
  Begin_Time = clock();
#endif
  for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
  {

    Proc_5();
    Proc_4();
      /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
    Int_1_Loc = 2;
    Int_2_Loc = 3;
    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
    Enum_Loc = Ident_2;
    Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
      /* Bool_Glob == 1 */
    while (Int_1_Loc < Int_2_Loc)  /* loop body executed once */
    {
      Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
        /* Int_3_Loc == 7 */
      Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
        /* Int_3_Loc == 7 */
      Int_1_Loc += 1;
    } /* while */
      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
    Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
      /* Int_Glob == 5 */
    Proc_1 (Ptr_Glob);
    for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
                             /* loop body executed twice */
    {
      if (Enum_Loc == Func_1 (Ch_Index, 'C'))
          /* then, not executed */
        {
        Proc_6 (Ident_1, &Enum_Loc);
        strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
        Int_2_Loc = Run_Index;
        Int_Glob = Run_Index;
        }
    }
      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
    Int_2_Loc = Int_2_Loc * Int_1_Loc;
    Int_1_Loc = Int_2_Loc / Int_3_Loc;
    Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
      /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
    Proc_2 (&Int_1_Loc);
      /* Int_1_Loc == 5 */

  } /* loop "for Run_Index" */
  /**************/
  /* Stop timer */
  /**************/
#ifdef TIMES
  times (&time_info);
  End_Time = (long) time_info.tms_utime;
#endif
#ifdef TIME
  End_Time = time ( (long *) 0);
#endif
#ifdef MSC_CLOCK
  End_Time = clock();
#endif

​ 以上就可以通过Begin_TimeEnd_Time获取运行程序的时间,在有以下的计算程序:

User_Time = End_Time - Begin_Time;

#ifdef TIME
	/*User_Time 已经是具体时间计数了*/
    Microseconds = (float) User_Time * Mic_secs_Per_Second 
                        / (float) Number_Of_Runs;
    Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
#else
	/*User_Time 是counter值*/
    Microseconds = (float) User_Time * Mic_secs_Per_Second 
                        / ((float) HZ * ((float) Number_Of_Runs));
    Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
                        / (float) User_Time;
#endif

​ 以user_time 是counter值为例:Dhrystones_Per_Second =Number_Of_Runs ÷ 时间 = Number_Of_Runs÷ (counter/频率) ,于是就有了上面的公式。

​ 对于一般的DMIP_MHZ,上面的结果还需要再除以一个频率,因为是xMhz 跑的,不是1Mhz 跑的。即

DMIP_MHZ = Dhrystones_Per_Second ÷(频率/1Mhz)例如 Dhrystones_Per_Second 为12,主频为5Mhz,那么结果就为12/5 = 2.4.

2.2 dhrystone 移植要点

​ 理解了第一点,这里就比较简单,其实和coremark 一样。只需要做好以下两点就可以了:

  • 提供时间基准,用于获取start time 和 end time ,一般为timer 的计数器。
  • 提供pintf 函数的重定义,用于打印。
  • 注意不要让计数器超过计数范围了。
posted @ 2024-02-28 18:52  Satellite98  阅读(1555)  评论(0)    收藏  举报