衡量处理器的一个重要指标是功耗,另外一个重要指标便是性能。在处理器领域的 Benchmarks 非常众多,有某些个人开发的程序,也有某些标准组织,或者商业公司开发的Benchmarks, 本文在此不加以一一枚举。 在嵌入式处理器领域最为知名和常见的 Benchmarks 为Dhrystone 和 CoreMark。
CoreMark是一个综合基准,用于测量嵌入式系统中使用的中央处理器(CPU)的性能。它是在2009由eembc的shay gal-on开发的,旨在成为一个行业标准,取代过时的dehrystone基准。代码用C编写,包含以下算法:列表处理(增删改查和排序)、矩阵操作(公共矩阵操作)、状态机(确定输入流是否包含有效数字)和CRC。[5]用户可以自由的下载Coremark,并移植到自己的平台上运行,随后就可以看到分数。
测试项目及文件函数解读
1、链接列表
(1)概要
core_list_join.c |
|
函数: |
|
core_bench_list |
Benchmark function |
cmp_complex |
比较列表单元格中的数据项。 |
cmp_idx |
比较列表单元格中的idx项目,并重新生成数据。 |
core_list_init |
用数据初始化列表。 |
core_list_insert |
将一个项目插入列表 |
core_list_remove |
从列表中删除一个项目。 |
core_list_undo_remove |
撤销删除操作。 |
core_list_find |
在列表中找到一个项目 |
core_list_reverse |
反转一个列表 |
core_list_mergesort |
在不递归的情况下对列表进行排序。 |
(2)描述
此Benchmark所做的项目 1.将一个项目插入列表2.从列表中删除一个项目。3.撤销删除操作。4.在列表中找到一个项目5.反转一个列表6.在不递归的情况下对列表进行排序。
虽然增加了间接访问数据的级别,但这种结构是现实的,可用于许多用于中小型列表的嵌入式应用程序。
列表本身将在将被传递给初始化函数的一块内存上初始化。尽管通常链表使用malloc作为新节点,但嵌入式应用程序有时会直接控制小数据结构(如数组和列表)的内存以避免系统调用的开销,因此这种方法是现实的。
链表将被初始化,以使得列表指针的四分之一指向存储器中的顺序区域,并且列表指针的三分之一以非顺序方式分布。这样做是为了模拟一个链接列表,其中添加/删除操作会暂时中断整齐的顺序,然后一系列可能来自连续内存位置的添加。
对于基准本身:
将执行多个查找操作。这些查找操作可能会导致整个列表被遍历。每次查找的结果将成为输出链的一部分。列表将使用基于data16值的合并排序进行排序,然后根据列表的一部分导出data16项目的CRC。CRC将成为产品链的一部分。
列表将使用基于idx值的合并排序再次排序。这种排序将保证列表在离开函数之前返回到主状态,这样函数的多次迭代将具有相同的结果。列表部分的data16的CRC将再次被计算并成为输出链的一部分。
每个单元中的实际数据16将根据单个16b输入进行伪随机编码,这些输入在编译时无法确定。此外,用于CRC的列表部分也将传递给该函数,并根据在运行时无法确定的输入来确定。
使用链接列表的基准。链接列表是许多应用程序中使用的常见数据结构。就我们的目的而言,这将锻炼处理器的内存单元。特别是使用列表指针来查找和更改数据。
其中没有使用Malloc,因为有些平台不支持这个库。
相反,被传入的内存块用于创建一个列表,并且该基准会小心不要添加更多项目,然后可以通过内存块调整。移植层将确保我们有一个有效的内存块。
所有操作均已完成,无需使用任何额外内存。
2、矩阵操纵基准
(1)概要
core_matrix.c |
|
函数: |
|
core_bench_matrix |
Benchmark function |
matrix_test |
执行矩阵操纵。 |
matrix_sum |
计算一个依赖于矩阵中元素值的函数。 |
matrix_mul_const |
用一个常数乘以一个矩阵。 |
matrix_add_const |
为矩阵的所有元素添加一个常量值。 |
matrix_mul_vect |
用一个矢量乘一个矩阵。 |
matrix_mul_matrix |
矩阵乘矩阵。 |
matrix_mul_matrix_bitextract |
矩阵乘矩阵,并从结果中提取一些位。 |
(2)描述
Matrixmanipulation benchmark,这个非常简单的算法构成了许多更复杂算法的基础。紧密的内部循环是许多优化(编译器以及基于硬件)的重点,因此与嵌入式处理相关。
它所做的测试包含1.用一个常数乘以一个矩阵。2.为矩阵的所有元素添加一个常量值。3.用一个矢量乘一个矩阵。4.用矩阵乘以一个矩阵。5.将矩阵乘以矩阵。6.并从结果中提取一些bits。
总可用数据空间将被分为3部分
NxN矩阵A 用较小的值初始化(上部3/4位全部为零)。
NxN矩阵B 初始化为中等值(上半部分全部为零)。
NxN矩阵C 用于结果。
A和B的实际值必须根据编译时不可用的输入来派生。
1、状态机基准
(1)概要
core_state.c |
|
函数: |
|
core_bench_state |
Benchmark function |
core_init_state |
初始化状态机的输入数据。 |
core_state_transition |
实际的状态机。 |
(2)描述
许多嵌入式产品都使用这种简单的状态机。对于更复杂的状态机,有时会使用状态转换表实现,而直接编码的交易速度易于维护。由于在CoreMark中使用状态机的主要目的是为了锻炼switch/if的运转情况,我们使用的是小型moore机器。特别是,这台机器测试字符串输入的类型,试图确定输入是数字还是别的东西。