一、Coremark简介
Coremark是一个由EEMBC(嵌入式微处理器基准委员会)开发的综合性测试,该测试可测量处理器的运行速度、内存速度、总线速度和I/O速度等因素。该测试与特定处理器器架构无关,在评估性能时更加客观准确。
二、Coremark测试适用的处理器
Coremark性能测试适用于所有类型的处理器,包括微控制器、微处理器和单片机等。该测试覆盖多个处理器的指令集和操作系统,并且可以在不同的编译器和优化级别下进行测试。
三、Coremark测试优势
Coremark测试具有以下优势:
- 可被广泛接受的基准测试。
- 代表综合性能而不是单一特性。
- 足够简洁以进行常规测试。
- 容易比较结果和公开的表格。
四、Coremark测试原理
Coremark测试是由一系列作为基准的C程序构成的,这些程序涉及多个任务以测试处理器的性能和能力。测试结果是基于一个标准分数,可以比较不同处理器的实际性能。
五、Coremark测试应用
Coremark测试可用于以下应用方面:
- 处理器厂商进行处理器性能评估和优化。
- 系统开发者评估和优化系统性能。
- 处理器和系统选择。
六、Coremark测试实例
下面是一个基本的Coremark测试C程序示例:
/* CoreMark test program */
/* Sponsored by CoreMark Committee and EEMBC */
/* Copyright (C) Embedded Microprocessor Benchmark Consortium (EEMBC)
* and Performa SRL(a Silvaco company) 2010-2016. All rights are reserved. */
/* Test application configuration */
#ifndef ITERATIONS
#define ITERATIONS 20000
#endif
#ifndef COMPILER
#define COMPILER "GCC"
#endif
#define UNUSED(x) (void)(x) /* for GNU */
/* Include files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
/* Local Constants */
#define VER "1.0.1"
#define MEM_STATIC 0
#define MEM_MALLOC 1
#define MEM_METHOD MEM_MALLOC
#define SEED_1 0x1234567L
#define SEED_2 0x56789ABL
#define SEED_3 0x9ABCDEF0L
#define UNROLL 8
#define COMPUTE_SIZE 1
#define MEM_SIZE ((size_t)1024*(size_t)8)
#define MAXBLOCKSIZE ((size_t)256)
#define C_ITERATIONS (ITERATIONS/UNROLL)
/* Local regression parameters */
#if defined(MEM_METHOD) && (MEM_METHOD==MEM_STATIC)
#define STATIC_PERFORMANCE_COPY_JPEG "21.34"
#define STATIC_PERFORMANCE_DECODE_JPEG "75.02"
#define STATIC_PERFORMANCE_UNPACK_TAR "27.91"
#define STATIC_PERFORMANCE_GSM "33.11"
#define STATIC_PERFORMANCE_CRC32 "57.68"
#define STATIC_PERFORMANCE_SHA "57.67"
#endif
/* Local variables */
static int seed1 = SEED_1;
static int seed2 = SEED_2;
static int seed3 = SEED_3;
static size_t block_size = 0;
static size_t *memblock;
static size_t memblock_size = MEM_SIZE;
/* Data */
#include "data.h"
/* Local functions */
static double CoreMark_main(size_t value);
static unsigned int get_seed(unsigned int seed);
/* Local memory functions */
#if defined(MEM_METHOD) && (MEM_METHOD == MEM_MALLOC)
static void *portable_malloc(size_t size) { return malloc(size); }
static void portable_free(void *p) { free(p); }
#define MEM_METHOD_DESC "C library malloc/free"
#elif defined(MEM_METHOD) && (MEM_METHOD==MEM_STATIC)
#define MAX_MEMBLOCKS 10
static size_t static_memory[MAX_MEMBLOCKS][MEM_SIZE/sizeof(size_t)];
static size_t *static_memblock = static_memory[0];
static int next_memblock = 1;
static void *portable_malloc(size_t size) {
void *p = NULL;
if (size > MEM_SIZE)
return NULL;
if ((static_memblock-memblock)+size > MEM_SIZE) {
if (next_memblock == MAX_MEMBLOCKS)
return NULL;
static_memblock = static_memory[next_memblock++];
}
p = static_memblock;
static_memblock += size;
return p;
}
static void portable_free(void *p) { UNUSED(p); return; }
#define MEM_METHOD_DESC "static array"
#elif defined(MEM_METHOD) && (MEM_METHOD==MEM_STACK)
/* This is to test stack allocation */
#define MEM_METHOD_DESC "stack area"
static void *portable_malloc(size_t size) { return NULL; }
static void portable_free(void *p) { UNUSED(p); return; }
#elif defined(MEM_METHOD) && (MEM_METHOD==MEM_LOCAL)
/* This is to test incorrect MADVISE settings, needs root privilege */
#define MEM_METHOD_DESC "local malloc/free"
static void *portable_malloc(size_t size) { return malloc(size); }
static void portable_free(void *p) { free(p); }
static void local_malloc_setup(void) {
#include <sys/mman.h>
#include <unistd.h>
long i, pagesize = getpagesize();
size_t maxsize = MEM_SIZE * MAXBLOCKSIZE / UNROLL;
char *p = (char *)malloc(maxsize+pagesize);
memblock = (size_t*)(p + pagesize - ((size_t)p % pagesize));
for (i=0; i < maxsize; i += pagesize)
madvise(((char*)memblock)+i, pagesize, MADV_DONTNEED);
memblock_size = maxsize;
}
#endif
int main(int argc, char *argv[]) {
double final_score;
size_t size;
/* Set up memory allocation functions */
#if defined(MEM_METHOD) && (MEM_METHOD == MEM_LOCAL)
/* Local allocator uses optional setup */
local_malloc_setup();
#else
/* Otherwise just plain malloc/free */
memblock = (size_t *)portable_malloc(MEM_SIZE);
if (!memblock) {
printf("Malloc failed!\n");
return -1;
}
#endif
/* Initialize with seed */
size = memblock_size / sizeof(size_t);
while (size--) {
memblock[size] = 0;
if (size > 3) {
memblock[size-1] = seed1;
memblock[size-2] = seed2;
memblock[size-3] = seed3;
size -= 3;
}
}
#if (defined(MEM_METHOD) && (MEM_METHOD==MEM_STATIC))
block_size = MAXBLOCKSIZE <= memblock_size/UNROLL ? MAXBLOCKSIZE : (memblock_size/UNROLL); /* Limit block size to MAXBLOCKSIZE */
#else
/* Find the biggest size that can be allocated */
block_size = 8*size; /* Limit block size to MAXBLOCKSIZE */
if (block_size > MAXBLOCKSIZE)
block_size = MAXBLOCKSIZE;
while (block_size > 8 && (portable_malloc(block_size) == NULL))
block_size -= 8;
portable_free(memblock);
memblock = NULL;
#else
block_size = MAXBLOCKSIZE <= memblock_size/UNROLL ? MAXBLOCKSIZE : (memblock_size/UNROLL);
#endif
#endif
/* Run the benchmark */
final_score = CoreMark_main(block_size);
/* Print the results */
printf("CoreMark Size : %zu\n", (size_t)(block_size*UNROLL));
printf("Iterations/Sec : %.2f\n", final_score);
printf("Compiler : %s\n", COMPILER);
#if defined(MEM_METHOD)
printf("Memory : %s %s\n", MEM_METHOD_DESC, MEM_METHOD==MEM_STATIC?"":(MEM_METHOD==MEM_LOCAL?"":(MEM_METHOD==MEM_STACK?"":"default C library")));
#endif
printf("Seed : %d,%d,%d\n", seed1, seed2, seed3);
return 0;
}
七、总结
通过对Coremark的详细阐述,我们了解到了Coremark测试的原理和应用场景,以及如何通过测试程序测试处理器的性能和能力。使用Coremark测试可以提高处理器的效率,选择更好的系统和处理器,更好地满足客户和市场需求。