static void statsPrint(struct statistic *statList) { struct statistic *statEl; boolean firstHeader = TRUE; double fixedMeasure = 1.0; statsHeader(); for (statEl = statList; statEl != NULL; statEl = statEl->next) { if (firstHeader) { printf("%5d%10d%8d%8d%10d%9d%8d%6d\n", statEl->chromCount, statEl->boundingElementCount, statEl->totalGaps, statEl->sizeZeroGapCount, statEl->maxGap, statEl->minGap, statEl->medianGap, statEl->meanGap); } if (statEl->placedItemCount) { double shoulderPercent = 100.0 * (double)statEl->placedWithinShoulder / (double)statEl->placedItemCount; if (firstHeader) { printf("Nearest neighbor statistics:\n"); printf(" # of Maximum Median Mean # within " "%% within # within ratio shoulder\n"); printf(" items nearest nearest nearest %d bp " "%dbp zero bp fixed/ran window\n", shoulder, shoulder); fixedMeasure = shoulderPercent; } printf("%8d%10d%8d%8d%9d %%%7.2f%9d%7.2f%8d\n", statEl->placedItemCount, statEl->maximumNearestNeighbor, statEl->medianNearestNeighbor, statEl->meanNearestNeighbor, statEl->placedWithinShoulder, shoulderPercent, statEl->zeroNeighbor, fixedMeasure/shoulderPercent, shoulder); } firstHeader = FALSE; } }
btInt TEST_MEM_PERF::test() { assert(initMem(vm["enable-warmup"].as<bool>(), vm["wrline-m"].as<bool>())); t_test_config config; memset(&config, 0, sizeof(config)); // What's the AFU frequency (MHz)? uint64_t afu_mhz = readCommonCSR(CSR_COMMON_FREQ); config.cycles = uint64_t(vm["ts"].as<int>()) * afu_mhz * 1000 * 1000; if (config.cycles == 0) { // Didn't specify --ts. Use cycles instead. config.cycles = uint64_t(vm["tc"].as<int>()); } const uint64_t counter_bits = 40; if (config.cycles & (int64_t(-1) << counter_bits)) { cerr << "Run length overflows " << counter_bits << " bit counter" << endl; exit(1); } config.vc = uint8_t(vm["vc"].as<int>()); assert(config.vc < 4); config.rdline_s = vm["rdline-s"].as<bool>(); config.wrline_m = vm["wrline-m"].as<bool>(); config.mcl = uint64_t(vm["mcl"].as<int>()); if ((config.mcl > 4) || (config.mcl == 3)) { cerr << "Illegal multi-line (mcl) parameter: " << config.mcl << endl; exit(1); } // Encode mcl as 3 bits. The low 2 are the Verilog t_ccip_clLen and the // high bit indicates random sizes. config.mcl = (config.mcl - 1) & 7; if (vm["test-mode"].as<bool>()) { cout << "# Mem Bytes, Stride, " << statsHeader() << endl; t_test_stats stats; config.buf_lines = 256; config.stride = 12; config.enable_writes = true; config.enable_reads = true; assert(runTest(&config, &stats) == 0); cout << 0x100 * CL(1) << " " << config.stride << " " << stats << endl; return 0; } uint64_t stride_incr = 1 + config.mcl; uint64_t min_stride = uint64_t(vm["min-stride"].as<int>()); min_stride = (min_stride + stride_incr - 1) & ~ (stride_incr - 1); uint64_t max_stride = uint64_t(vm["max-stride"].as<int>()) + 1; bool vcmap_all = vm["vcmap-all"].as<bool>(); bool vcmap_enable = vm["vcmap-enable"].as<bool>(); bool vcmap_dynamic = vm["vcmap-dynamic"].as<bool>(); int32_t vcmap_fixed_vl0_ratio = int32_t(vm["vcmap-fixed"].as<int>()); cout << "# MCL = " << (config.mcl + 1) << endl << "# Cycles per test = " << config.cycles << endl << "# AFU MHz = " << afu_mhz << endl << "# VC = " << vcNumToName(config.vc) << endl << "# VC Map enabled: " << (vcmap_enable ? "true" : "false") << endl; if (vcmap_enable) { cout << "# VC Map all: " << (vcmap_all ? "true" : "false") << endl << "# VC Map dynamic: " << (vcmap_dynamic ? "true" : "false") << endl; if (! vcmap_dynamic) { cout << "# VC Map fixed VL0 ratio: " << vcmap_fixed_vl0_ratio << " / 64" << endl; } } // Read cout << "#" << endl << "# Reads " << (config.rdline_s ? "" : "not ") << "cached" << endl << "# Mem Bytes, Stride, " << statsHeader() << endl; for (uint64_t mem_lines = stride_incr; mem_lines * CL(1) <= buffer_bytes; mem_lines <<= 1) { config.buf_lines = mem_lines; // Vary stride uint64_t stride_limit = (mem_lines < max_stride ? mem_lines+1 : max_stride); for (uint64_t stride = min_stride; stride < stride_limit; stride += stride_incr) { t_test_stats stats; config.stride = stride; config.enable_writes = false; config.enable_reads = true; assert(runTest(&config, &stats) == 0); cout << mem_lines * CL(1) << " " << stride << " " << stats << endl; } } // Write cout << endl << endl << "# Writes " << (config.wrline_m ? "" : "not ") << "cached" << endl << "# Mem Bytes, Stride, " << statsHeader() << endl; for (uint64_t mem_lines = stride_incr; mem_lines * CL(1) <= buffer_bytes; mem_lines <<= 1) { config.buf_lines = mem_lines; // Vary stride uint64_t stride_limit = (mem_lines < max_stride ? mem_lines+1 : max_stride); for (uint64_t stride = min_stride; stride < stride_limit; stride += stride_incr) { t_test_stats stats; config.stride = stride; config.enable_writes = true; config.enable_reads = false; assert(runTest(&config, &stats) == 0); cout << mem_lines * CL(1) << " " << stride << " " << stats << endl; } } // Throughput (independent read and write) cout << endl << endl << "# Reads " << (config.rdline_s ? "" : "not ") << "cached +" << " Writes " << (config.wrline_m ? "" : "not ") << "cached" << endl << "# Mem Bytes, Stride, " << statsHeader() << endl; for (uint64_t mem_lines = stride_incr; mem_lines * CL(1) <= buffer_bytes; mem_lines <<= 1) { config.buf_lines = mem_lines; // Vary stride uint64_t stride_limit = (mem_lines < max_stride ? mem_lines+1 : max_stride); for (uint64_t stride = min_stride; stride < stride_limit; stride += stride_incr) { t_test_stats stats; config.stride = stride; config.enable_writes = true; config.enable_reads = true; assert(runTest(&config, &stats) == 0); cout << mem_lines * CL(1) << " " << stride << " " << stats << endl; } } return 0; }