diff --git a/apps/microbench/README.md b/apps/microbench/README.md index ec47f49d..615042c8 100644 --- a/apps/microbench/README.md +++ b/apps/microbench/README.md @@ -9,9 +9,12 @@ CPU正确性和性能测试用基准程序。对AbstractMachine的要求: ## 使用方法 -同一组程序分成两组:test和ref。test数据规模很小,作为测试用。ref测试规模较大,作为衡量CPU性能用。 +同一组程序分成三组:test,train和ref。 +test数据规模很小,作为测试用,不计时不评分。 +train数据规模中等,可用于在仿真环境研究微结构行为,计时不评分。 +ref数据规模较大,作为衡量CPU性能用,计时并评分。 -默认编译ref数据规模,使用`make INPUT=TEST`编译test数据规模。 +默认编译ref数据规模,使用`make INPUT=TEST`编译test数据规模,使用`make INPUT=TRAIN`编译train数据规模。 ## 评分根据 @@ -21,14 +24,14 @@ CPU正确性和性能测试用基准程序。对AbstractMachine的要求: ## 已有的基准程序 -| 名称 | 描述 | 堆区使用 | +| 名称 | 描述 | ref堆区使用 | | ----- | ------------------------------------ | ----- | | qsort | 快速排序随机整数数组 | 640KB | | queen | 位运算实现的n皇后问题 | 0 | | bf | Brainf**k解释器,快速排序输入的字符串 | 32KB | | fib | Fibonacci数列f(n)=f(n-1)+…+f(n-m)的矩阵求解 | 256KB | | sieve | Eratosthenes筛法求素数 | 2MB | -| 15pz | A*算法求解4x4数码问题 | 8MB | +| 15pz | A*算法求解4x4数码问题 | 2MB | | dinic | Dinic算法求解二分图最大流 | 1MB | | lzip | Lzip数据压缩 | 4MB | | ssort | Skew算法后缀排序 | 4MB | diff --git a/apps/microbench/include/benchmark.h b/apps/microbench/include/benchmark.h index e9794dac..f700574a 100644 --- a/apps/microbench/include/benchmark.h +++ b/apps/microbench/include/benchmark.h @@ -17,55 +17,68 @@ extern "C" { #define REF_CPU "i7-7700K @ 4.20GHz" #define REF_SCORE 100000 -#ifdef SETTING_TEST +#if defined(SETTING_TEST) #define SETTING 0 + #define SETTING_NAME "TEST" +#elif defined(SETTING_TRAIN) + #define SETTING 1 + #define SETTING_NAME "TRAIN" +#elif defined(SETTING_REF) + #define SETTING 2 + #define SETTING_NAME "REF" #else - #ifdef SETTING_REF - #define SETTING 1 - #else - #error "Must define SETTING_TEST or SETTING_REF" - #endif + #error "Must define SETTING_TEST, SETTING_TRAIN or SETTING_REF" #endif #define REPEAT 1 -// size | heap | time | checksum -#define QSORT_SM { 100, 1 KB, 0, 0x08467105} -#define QSORT_LG { 100000, 640 KB, 5114, 0xed8cff89} -#define QUEEN_SM { 8, 0 KB, 0, 0x0000005c} -#define QUEEN_LG { 12, 0 KB, 4707, 0x00003778} -#define BF_SM { 4, 32 KB, 0, 0xa6f0079e} -#define BF_LG { 180, 32 KB, 23673, 0x9221e2b3} -#define FIB_SM { 2, 1 KB, 0, 0x7cfeddf0} -#define FIB_LG { 91, 256 KB, 28318, 0xebdc5f80} -#define SIEVE_SM { 100, 1 KB, 0, 0x00000019} -#define SIEVE_LG {10000000, 2 MB, 39361, 0x000a2403} -#define PZ15_SM { 0, 1 KB, 0, 0x00000006} -#define PZ15_LG { 1, 8 MB, 4486, 0x00068b8c} -#define DINIC_SM { 10, 8 KB, 0, 0x0000019c} -#define DINIC_LG { 128, 1 MB, 10882, 0x0000c248} -#define LZIP_SM { 128, 128 KB, 0, 0xb2581709} -#define LZIP_LG { 1048576, 4 MB, 24456, 0x43601310} -#define SSORT_SM { 100, 4 KB, 0, 0x4c555e09} -#define SSORT_LG { 100000, 4 MB, 4504, 0x4f0ab431} -#define MD5_SM { 100, 1 KB, 0, 0xf902f28f} -#define MD5_LG {10000000, 16 MB, 17239, 0x27286a42} +// size | heap | time | checksum +#define QSORT_S { 100, 1 KB, 0, 0x08467105} +#define QSORT_M { 30000, 128 KB, 0, 0xa3e99fe4} +#define QSORT_L { 100000, 640 KB, 5114, 0xed8cff89} +#define QUEEN_S { 8, 0 KB, 0, 0x0000005c} +#define QUEEN_M { 11, 0 KB, 0, 0x00000a78} +#define QUEEN_L { 12, 0 KB, 4707, 0x00003778} +#define BF_S { 4, 32 KB, 0, 0xa6f0079e} +#define BF_M { 25, 32 KB, 0, 0xa88f8a65} +#define BF_L { 180, 32 KB, 23673, 0x9221e2b3} +#define FIB_S { 2, 1 KB, 0, 0x7cfeddf0} +#define FIB_M { 23, 16 KB, 0, 0x94ad8800} +#define FIB_L { 91, 256 KB, 28318, 0xebdc5f80} +#define SIEVE_S { 100, 1 KB, 0, 0x00000019} +#define SIEVE_M { 200000, 32 KB, 0, 0x00004640} +#define SIEVE_L {10000000, 2 MB, 39361, 0x000a2403} +#define PZ15_S { 0, 1 KB, 0, 0x00000006} +#define PZ15_M { 1, 256 KB, 0, 0x0000b0df} +#define PZ15_L { 2, 2 MB, 4486, 0x00068b8c} +#define DINIC_S { 10, 8 KB, 0, 0x0000019c} +#define DINIC_M { 80, 512 KB, 0, 0x00004f99} +#define DINIC_L { 128, 1 MB, 10882, 0x0000c248} +#define LZIP_S { 128, 128 KB, 0, 0xb2581709} +#define LZIP_M { 50000, 1 MB, 0, 0x275df291} +#define LZIP_L { 1048576, 4 MB, 24456, 0x43601310} +#define SSORT_S { 100, 4 KB, 0, 0x4c555e09} +#define SSORT_M { 10000, 512 KB, 0, 0x0db7909b} +#define SSORT_L { 100000, 4 MB, 4504, 0x4f0ab431} +#define MD5_S { 100, 1 KB, 0, 0xf902f28f} +#define MD5_M { 200000, 256 KB, 0, 0xd4f9bc6d} +#define MD5_L {10000000, 16 MB, 17239, 0x27286a42} #define BENCHMARK_LIST(def) \ - def(qsort, "qsort", QSORT_SM, QSORT_LG, "Quick sort") \ - def(queen, "queen", QUEEN_SM, QUEEN_LG, "Queen placement") \ - def( bf, "bf", BF_SM, BF_LG, "Brainf**k interpreter") \ - def( fib, "fib", FIB_SM, FIB_LG, "Fibonacci number") \ - def(sieve, "sieve", SIEVE_SM, SIEVE_LG, "Eratosthenes sieve") \ - def( 15pz, "15pz", PZ15_SM, PZ15_LG, "A* 15-puzzle search") \ - def(dinic, "dinic", DINIC_SM, DINIC_LG, "Dinic's maxflow algorithm") \ - def( lzip, "lzip", LZIP_SM, LZIP_LG, "Lzip compression") \ - def(ssort, "ssort", SSORT_SM, SSORT_LG, "Suffix sort") \ - def( md5, "md5", MD5_SM, MD5_LG, "MD5 digest") \ + def(qsort, "qsort", QSORT_S, QSORT_M, QSORT_L, "Quick sort") \ + def(queen, "queen", QUEEN_S, QUEEN_M, QUEEN_L, "Queen placement") \ + def( bf, "bf", BF_S, BF_M, BF_L, "Brainf**k interpreter") \ + def( fib, "fib", FIB_S, FIB_M, FIB_L, "Fibonacci number") \ + def(sieve, "sieve", SIEVE_S, SIEVE_M, SIEVE_L, "Eratosthenes sieve") \ + def( 15pz, "15pz", PZ15_S, PZ15_M, PZ15_L, "A* 15-puzzle search") \ + def(dinic, "dinic", DINIC_S, DINIC_M, DINIC_L, "Dinic's maxflow algorithm") \ + def( lzip, "lzip", LZIP_S, LZIP_M, LZIP_L, "Lzip compression") \ + def(ssort, "ssort", SSORT_S, SSORT_M, SSORT_L, "Suffix sort") \ + def( md5, "md5", MD5_S, MD5_M, MD5_L, "MD5 digest") \ // Each benchmark will run REPEAT times -#define DECL(_name, _sname, _s1, _s2, _desc) \ +#define DECL(_name, _sname, _s, _m, _l, _desc) \ void bench_##_name##_prepare(); \ void bench_##_name##_run(); \ int bench_##_name##_validate(); @@ -83,7 +96,7 @@ typedef struct Benchmark { void (*run)(); int (*validate)(); const char *name, *desc; - Setting settings[2]; + Setting settings[3]; } Benchmark; extern Benchmark *current; diff --git a/apps/microbench/src/15pz/15pz.cpp b/apps/microbench/src/15pz/15pz.cpp index 7a952473..804fec14 100644 --- a/apps/microbench/src/15pz/15pz.cpp +++ b/apps/microbench/src/15pz/15pz.cpp @@ -3,27 +3,36 @@ #include "heap.h" const int N = 4; -#ifdef SETTING_REF -const int MAXN = 65536; -#else +#if defined(SETTING_REF) +const int MAXN = 16384; +#elif defined(SETTING_TRAIN) +const int MAXN = 2048; +#elif defined(SETTING_TEST) const int MAXN = 10; #endif -static int PUZZLE_SM[N*N] = { +static int PUZZLE_S[N*N] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 11, 13, 14, 15, 12, }; -static int PUZZLE_LG[N*N] = { +static int PUZZLE_M[N*N] = { + 1, 2, 3, 4, + 5, 6, 7, 8, + 12, 0, 14, 13, + 11, 15, 10, 9, +}; + +static int PUZZLE_L[N*N] = { 0, 2, 3, 4, 9, 6, 7, 8, 5, 11, 10, 12, 1, 15, 13, 14, }; -int ans; +static int ans; extern "C" { @@ -33,10 +42,11 @@ void bench_15pz_prepare() { void bench_15pz_run() { N_puzzle puzzle; - if (setting->size == 0) { - puzzle = N_puzzle(PUZZLE_SM); - } else { - puzzle = N_puzzle(PUZZLE_LG); + switch (setting->size) { + case 0: puzzle = N_puzzle(PUZZLE_S); break; + case 1: puzzle = N_puzzle(PUZZLE_M); break; + case 2: puzzle = N_puzzle(PUZZLE_L); break; + default: assert(0); } assert(puzzle.solvable()); diff --git a/apps/microbench/src/bench.c b/apps/microbench/src/bench.c index 035d39be..f544008b 100644 --- a/apps/microbench/src/bench.c +++ b/apps/microbench/src/bench.c @@ -12,13 +12,13 @@ static char *hbrk; // The benchmark list -#define ENTRY(_name, _sname, _s1, _s2, _desc) \ +#define ENTRY(_name, _sname, _s, _m, _l, _desc) \ { .prepare = bench_##_name##_prepare, \ .run = bench_##_name##_run, \ .validate = bench_##_name##_validate, \ .name = _sname, \ .desc = _desc, \ - .settings = {_s1, _s2}, }, + .settings = {_s, _m, _l}, }, Benchmark benchmarks[] = { BENCHMARK_LIST(ENTRY) @@ -62,7 +62,7 @@ static unsigned long score(Benchmark *b, unsigned long tsc, unsigned long msec) int main() { _ioe_init(); - printk("======= Running MicroBench [INPUT *%s*] =======\n", SETTING ? "REF" : "TEST"); + printk("======= Running MicroBench [INPUT *%s*] =======\n", SETTING_NAME); unsigned long bench_score = 0; int pass = 1; @@ -108,7 +108,7 @@ int main() { printk("==================================================\n"); printk("MicroBench %s", pass ? "PASS" : "FAIL"); - if (SETTING != 0) { + if (SETTING == 2) { printk(" %d Marks\n", (unsigned int)bench_score); printk(" vs. %d Marks (%s)\n", REF_SCORE, REF_CPU); } else { diff --git a/apps/microbench/src/dinic/dinic.cpp b/apps/microbench/src/dinic/dinic.cpp index e9dbe943..479ceb90 100644 --- a/apps/microbench/src/dinic/dinic.cpp +++ b/apps/microbench/src/dinic/dinic.cpp @@ -1,9 +1,11 @@ #include static int N; -#ifdef SETTING_REF +#if defined(SETTING_REF) # define MAXN 128 -#else +#elif defined(SETTING_TRAIN) +# define MAXN 80 +#elif defined(SETTING_TEST) # define MAXN 10 #endif #define MAXM (MAXN * MAXN + MAXN * 2) * 2 diff --git a/apps/microbench/src/lzip/quicklz.h b/apps/microbench/src/lzip/quicklz.h index 3f1e9436..41736b92 100644 --- a/apps/microbench/src/lzip/quicklz.h +++ b/apps/microbench/src/lzip/quicklz.h @@ -46,10 +46,10 @@ static inline void* bench_memcpy(void* dst, const void* src, size_t n){ //#define QLZ_COMPRESSION_LEVEL 1 //#define QLZ_COMPRESSION_LEVEL 2 //#define QLZ_COMPRESSION_LEVEL 3 -#ifdef SETTING_REF - #define QLZ_COMPRESSION_LEVEL 3 -#else +#ifdef SETTING_TEST #define QLZ_COMPRESSION_LEVEL 1 +#else + #define QLZ_COMPRESSION_LEVEL 3 #endif // If > 0, zero out both states prior to first call to qlz_compress() or qlz_decompress()