From 3863ad27814eefe2d26b2eba7eb8a4ab65bef5a4 Mon Sep 17 00:00:00 2001 From: Wilson Fung Date: Wed, 24 Oct 2012 23:45:37 -0800 Subject: Updated the option parser to support named sub-options (via a separate instance of option parser). Changed DRAM timing options to use this new format. [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 14457] --- CHANGES | 4 ++ configs/GTX480/gpgpusim.config | 9 +--- configs/QuadroFX5800/gpgpusim.config | 3 +- configs/TeslaC2050/gpgpusim.config | 9 +--- src/gpgpu-sim/gpu-sim.h | 45 +++++++++++++--- src/option_parser.cc | 101 ++++++++++++++++++++++++++++------- src/option_parser.h | 5 ++ 7 files changed, 135 insertions(+), 41 deletions(-) diff --git a/CHANGES b/CHANGES index 5e4d93f..29d1926 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,10 @@ Version 3.1.1+edits (development branch) versus 3.1.1 - Enabled configurable cache policies (write-back, write-through) and implemented a write-allocate policy - Added functional execution support for shared memory atomic operations +- Updated the option parser to support strings delimited by characters such as + '=' and ';'. This allow options with a long string of sub-options (e.g. DRAM + timing) to have a more friendly format. +- Changed the DRAM timing option to a more reader-friendly format. - Bug Fixes: - Fixed a compile error that happens with newer gcc/g++ versions (4.7.1) - Fixed a bug with the association between cuobjdump output and cubin diff --git a/configs/GTX480/gpgpusim.config b/configs/GTX480/gpgpusim.config index a8eac01..fd23e57 100644 --- a/configs/GTX480/gpgpusim.config +++ b/configs/GTX480/gpgpusim.config @@ -83,13 +83,8 @@ # GDDR5 timing from hynix H5GQ1H24AFR # to disable bank groups, set nbkgrp to 1 and tCCDL and tRTPL to 0 -# {nbk:tCCD:tRRD:tRCD:tRAS:tRP:tRC:CL:WL:tCDLR:tWR:nbkgrp:tCCDL:tRTPL} -# -gpgpu_dram_timing_opt nbk=16:CCD=2:RRD=6:RCD=12:RAS=28:RP=12:RC=40:CL=12: -# WL=4:CDLR=5:WR=12:nbkgrp=4:CCDL=3:RTPL=2 --gpgpu_dram_timing_opt 16:2:6:12:28:12:40:12:4:5:12:4:3:2 - -# GDDR3 -#-gpgpu_dram_timing_opt 8:2:8:12:25:10:35:10:7:6:11 +-gpgpu_dram_timing_opt "nbk=16:CCD=2:RRD=6:RCD=12:RAS=28:RP=12:RC=40: + CL=12:WL=4:CDLR=5:WR=12:nbkgrp=4:CCDL=3:RTPL=2" # Fermi has two schedulers per core -gpgpu_num_sched_per_core 2 diff --git a/configs/QuadroFX5800/gpgpusim.config b/configs/QuadroFX5800/gpgpusim.config index 638f362..903c12e 100644 --- a/configs/QuadroFX5800/gpgpusim.config +++ b/configs/QuadroFX5800/gpgpusim.config @@ -55,8 +55,7 @@ -gpgpu_mem_address_mask 1 -gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RRBBBCCC.CCCSSSSS # GDDR3 timing from Samsung K4J52324QH-HC12 @ 800MHz -# {nbk:tCCD:tRRD:tRCD:tRAS:tRP:tRC:CL:WL:tCDLR:tWR:nbkgrp:tCCDL:tRTPL} --gpgpu_dram_timing_opt 8:2:8:12:25:10:35:10:7:6:11:1:0:0 +-gpgpu_dram_timing_opt nbk=8:CCD=2:RRD=8:RCD=12:RAS=25:RP=10:RC=35:CL=10:WL=7:CDLR=6:WR=11 # stat collection -gpgpu_memlatency_stat 14 diff --git a/configs/TeslaC2050/gpgpusim.config b/configs/TeslaC2050/gpgpusim.config index f09e391..86f0d85 100644 --- a/configs/TeslaC2050/gpgpusim.config +++ b/configs/TeslaC2050/gpgpusim.config @@ -84,13 +84,8 @@ # GDDR5 timing from hynix H5GQ1H24AFR # to disable bank groups, set nbkgrp to 1 and tCCDL and tRTPL to 0 -# {nbk:tCCD:tRRD:tRCD:tRAS:tRP:tRC:CL:WL:tCDLR:tWR:nbkgrp:tCCDL:tRTPL} -# -gpgpu_dram_timing_opt nbk=16:CCD=2:RRD=6:RCD=12:RAS=28:RP=12:RC=40:CL=12: -# WL=4:CDLR=5:WR=12:nbkgrp=4:CCDL=3:RTPL=2 --gpgpu_dram_timing_opt 16:2:6:12:28:12:40:12:4:5:12:4:3:2 - -# GDDR3 -#-gpgpu_dram_timing_opt 8:2:8:12:25:10:35:10:7:6:11 +-gpgpu_dram_timing_opt "nbk=16:CCD=2:RRD=6:RCD=12:RAS=28:RP=12:RC=40: + CL=12:WL=4:CDLR=5:WR=12:nbkgrp=4:CCDL=3:RTPL=2" # Fermi has two schedulers per core -gpgpu_num_sched_per_core 2 diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index ac2be00..d5b810f 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -28,6 +28,7 @@ #ifndef GPU_SIM_H #define GPU_SIM_H +#include "../option_parser.h" #include "../abstract_hardware_model.h" #include "addrdec.h" #include "shader.h" @@ -71,20 +72,50 @@ struct memory_config { } void init() { - //Disabling bank groups if their values are not specified - nbkgrp = 1; - tCCDL = 0; - tRTPL = 0; assert(gpgpu_dram_timing_opt); - sscanf(gpgpu_dram_timing_opt,"%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", - &nbk,&tCCD,&tRRD,&tRCD,&tRAS,&tRP,&tRC,&CL,&WL,&tCDLR,&tWR,&nbkgrp,&tCCDL,&tRTPL); + if (strchr(gpgpu_dram_timing_opt, '=') == NULL) { + // dram timing option in ordered variables (legacy) + // Disabling bank groups if their values are not specified + nbkgrp = 1; + tCCDL = 0; + tRTPL = 0; + sscanf(gpgpu_dram_timing_opt,"%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", + &nbk,&tCCD,&tRRD,&tRCD,&tRAS,&tRP,&tRC,&CL,&WL,&tCDLR,&tWR,&nbkgrp,&tCCDL,&tRTPL); + } else { + // named dram timing options (unordered) + option_parser_t dram_opp = option_parser_create(); + + option_parser_register(dram_opp, "nbk", OPT_UINT32, &nbk, "number of banks", ""); + option_parser_register(dram_opp, "CCD", OPT_UINT32, &tCCD, "column to column delay", ""); + option_parser_register(dram_opp, "RRD", OPT_UINT32, &tRRD, "minimal delay between activation of rows in different banks", ""); + option_parser_register(dram_opp, "RCD", OPT_UINT32, &tRCD, "row to column delay", ""); + option_parser_register(dram_opp, "RAS", OPT_UINT32, &tRAS, "time needed to activate row", ""); + option_parser_register(dram_opp, "RP", OPT_UINT32, &tRP, "time needed to precharge (deactivate) row", ""); + option_parser_register(dram_opp, "RC", OPT_UINT32, &tRC, "row cycle time", ""); + option_parser_register(dram_opp, "CDLR", OPT_UINT32, &tCDLR, "switching from write to read (changes tWTR)", ""); + option_parser_register(dram_opp, "WR", OPT_UINT32, &tWR, "last data-in to row precharge", ""); + + option_parser_register(dram_opp, "CL", OPT_UINT32, &CL, "CAS latency", ""); + option_parser_register(dram_opp, "WL", OPT_UINT32, &WL, "Write latency", ""); + + //Disabling bank groups if their values are not specified + option_parser_register(dram_opp, "nbkgrp", OPT_UINT32, &nbkgrp, "number of bank groups", "1"); + option_parser_register(dram_opp, "CCDL", OPT_UINT32, &tCCDL, "column to column delay between accesses to different bank groups", "0"); + option_parser_register(dram_opp, "RTPL", OPT_UINT32, &tRTPL, "read to precharge delay between accesses to different bank groups", "0"); + + option_parser_delimited_string(dram_opp, gpgpu_dram_timing_opt, "=:;"); + fprintf(stdout, "DRAM Timing Options:\n"); + option_parser_print(dram_opp, stdout); + option_parser_destroy(dram_opp); + } + int nbkt = nbk/nbkgrp; unsigned i; for (i=0; nbkt>0; i++) { nbkt = nbkt>>1; } bk_tag_length = i; - assert(nbkgrp>0 && "Number of bank groups cannot be zero"); + assert(nbkgrp>0 && "Number of bank groups cannot be zero"); tRCDWR = tRCD-(WL+1); tRTW = (CL+(BL/data_command_freq_ratio)+2-WL); tWTR = (WL+(BL/data_command_freq_ratio)+tCDLR); diff --git a/src/option_parser.cc b/src/option_parser.cc index 2c50b47..4133d15 100644 --- a/src/option_parser.cc +++ b/src/option_parser.cc @@ -45,21 +45,23 @@ class OptionRegistryInterface { public: OptionRegistryInterface(const string optionName, const string optionDesc) - : m_optionName(optionName), m_optionDesc(optionDesc) + : m_optionName(optionName), m_optionDesc(optionDesc), m_isParsed(false) {} virtual ~OptionRegistryInterface() {} const string& GetName() { return m_optionName; } const string& GetDesc() { return m_optionDesc; } + const bool isParsed() { return m_isParsed; } virtual string toString() = 0; virtual bool fromString(const string str) = 0; virtual bool isFlag() = 0; - virtual bool assignDefault(const char *str) = 0; + virtual bool assignDefault(const char *str) = 0; -private: +protected: string m_optionName; string m_optionDesc; + bool m_isParsed; // true if the target variable has been updated by fromString() }; // Template for option registry - class T = specify data type of the option @@ -99,11 +101,12 @@ public: } catch (stringstream::failure &e) { return false; } + m_isParsed = true; return true; } virtual bool isFlag() { return false; } - virtual bool assignDefault(const char *str) { return fromString(str); } + virtual bool assignDefault(const char *str) { return fromString(str); } operator T() { @@ -119,6 +122,7 @@ template<> bool OptionRegistry::fromString(const string str) { m_variable = str; + m_isParsed = true; return true; } @@ -128,6 +132,7 @@ bool OptionRegistry::fromString(const string str) { m_variable = new char[str.size() + 1]; strcpy(m_variable, str.c_str()); + m_isParsed = true; return true; } @@ -136,6 +141,7 @@ template<> bool OptionRegistry::assignDefault(const char *str) { m_variable = const_cast(str); // c-string options are not meant to be edited anyway + m_isParsed = true; return true; } @@ -167,6 +173,7 @@ bool OptionRegistry::fromString(const string str) } assert(value == 0 or value == 1); // sanity check for boolean options (it can only be 1 or 0) m_variable = (value != 0); + m_isParsed = true; return parsed; } @@ -193,7 +200,7 @@ public: OptionRegistry *p_option = new OptionRegistry(optionName, optionDesc, optionVariable); m_optionReg.push_back(p_option); m_optionMap[optionName] = p_option; - p_option->assignDefault(optionDefault); + p_option->assignDefault(optionDefault); } void ParseCommandLine(int argc, const char * const argv[]) @@ -257,6 +264,26 @@ public: } inputFile.close(); + ParseStringStream(args); + } + + // parse the given string as tokens separated by a set of given delimiters + void ParseString(string inputString, const string delimiters = string(" ;")) { + // convert all delimiter characters into whitespaces + for (unsigned t = 0; t < inputString.size(); t++) { + for (unsigned d = 0; d < delimiters.size(); d++) { + if (inputString[t] == delimiters.at(d)) { + inputString[t] = ' '; + break; + } + } + } + stringstream args(inputString); + ParseStringStream(args); + } + + // parse the given stringstream as whitespace-separated tokens. drain the stream in the process + void ParseStringStream(stringstream &args) { // extract non-whitespace string tokens vector argv; argv.push_back(new char[6]); @@ -298,6 +325,10 @@ public: OptionCollection::iterator i_option; for (i_option = m_optionReg.begin(); i_option != m_optionReg.end(); ++i_option) { stringstream sout; + if ((*i_option)->isParsed() == false) { + cerr << "\n\nGPGPU-Sim ** ERROR: Missing option '" << (*i_option)->GetName() << "'\n"; + assert(0); + } sout << setw(20) << left << (*i_option)->GetName() << " "; sout << setw(20) << right << (*i_option)->toString() << " # "; sout << left << (*i_option)->GetDesc(); @@ -343,6 +374,7 @@ void option_parser_register(option_parser_t opp, case OPT_BOOL: p_opr->Register(name, desc, *(bool*)variable, defaultvalue); break; case OPT_FLOAT: p_opr->Register(name, desc, *(float*)variable, defaultvalue); break; case OPT_DOUBLE: p_opr->Register(name, desc, *(double*)variable, defaultvalue); break; + case OPT_CHAR: p_opr->Register(name, desc, *(char*)variable, defaultvalue); break; case OPT_CSTR: p_opr->Register(name, desc, *(char**)variable, defaultvalue); break; default: fprintf(stderr, "\n\nGPGPU-Sim ** ERROR: option data type (%d) not supported!\n", type); @@ -365,6 +397,14 @@ void option_parser_cfgfile(option_parser_t opp, p_opr->ParseFile(filename); } +void option_parser_delimited_string(option_parser_t opp, + const char *inputstring, + const char *delimiters) +{ + OptionParser *p_opr = reinterpret_cast(opp); + p_opr->ParseString(inputstring, delimiters); +} + void option_parser_print(option_parser_t opp, FILE *fout) { @@ -398,7 +438,7 @@ public: }; -int cppinterfacetest(int argc, char *argv[]) +int cppinterfacetest(int argc, const char *argv[]) { testtype c; OptionParser optionparser; @@ -430,22 +470,22 @@ int cppinterfacetest(int argc, char *argv[]) return 0; } -int cinterfacetest(int argc, char *argv[]) +int cinterfacetest(int argc, const char *argv[]) { testtype c; option_parser_t opp = option_parser_create(); c.idata = 123; c.fdata = 3249586.333; c.sdata = string("haha"); - char *otherstr; + char *otherstr; - option_parser_register(opp, "-idata", OPT_INT32, &c.idata, "integer data", "-456"); - option_parser_register(opp, "-fdata", OPT_FLOAT, &c.fdata, "floating point data", "0.001"); - option_parser_register(opp, "-sdata", OPT_CSTR, &otherstr, "first string data", "hellow"); - option_parser_register(opp, "-ulldata", OPT_UINT64, &c.ulldata, "unsigend long long data", "0x123456789abcdef1"); - option_parser_register(opp, "-someflag", OPT_BOOL, &c.bdata, "first flag", "0"); - option_parser_register(opp, "-otherflag", OPT_BOOL, &c.boolint, "second flag", "1"); - option_parser_register(opp, "-coption", OPT_CSTR, &c.coption, "char * data", NULL); + option_parser_register(opp, "-idata", OPT_INT32, &c.idata, "integer data", "-456"); + option_parser_register(opp, "-fdata", OPT_FLOAT, &c.fdata, "floating point data", "0.001"); + option_parser_register(opp, "-sdata", OPT_CSTR, &otherstr, "first string data", "hellow"); + option_parser_register(opp, "-ulldata", OPT_UINT64, &c.ulldata, "unsigend long long data", "0x123456789abcdef1"); + option_parser_register(opp, "-someflag", OPT_BOOL, &c.bdata, "first flag", "0"); + option_parser_register(opp, "-otherflag", OPT_BOOL, &c.boolint, "second flag", "1"); + option_parser_register(opp, "-coption", OPT_CSTR, &c.coption, "char * data", NULL); printf("Default: \n"); option_parser_print(opp, stdout); @@ -458,17 +498,42 @@ int cinterfacetest(int argc, char *argv[]) option_parser_cfgfile(opp, "test.config"); printf("File Parse Results: \n"); option_parser_print(opp, stdout); - printf("%s %d\n", otherstr, c.idata); + printf("%s %d\n", otherstr, c.idata); - option_parser_destroy(opp); + option_parser_destroy(opp); return 0; } -int main(int argc, char *argv[]) +int stringparsertest() +{ + int tABC; + int tDEF; + char tMode; + char *tName; + + option_parser_t opp = option_parser_create(); + option_parser_register(opp, "ABC", OPT_INT32, &tABC, "tABC", "34"); + option_parser_register(opp, "DEF", OPT_INT32, &tDEF, "tDEF", "-56"); + option_parser_register(opp, "Mode", OPT_CHAR, &tMode, "tMode", "P"); + option_parser_register(opp, "Name", OPT_CSTR, &tName, "tName", "Cache"); + + option_parser_delimited_string(opp, "ABC 1111; DEF 88; Mode A; Name out", " ;"); + printf("String Parse Results: \n"); + option_parser_print(opp, stdout); + + option_parser_delimited_string(opp, "Name=dram;DEF=702;Mode=B;ABC=-9573;", " =;"); + printf("String Parse Results: \n"); + option_parser_print(opp, stdout); + + return 0; +} + +int main(int argc, const char *argv[]) { cppinterfacetest(argc,argv); cinterfacetest(argc,argv); + stringparsertest(); return 0; } diff --git a/src/option_parser.h b/src/option_parser.h index 198ed01..fdfd156 100644 --- a/src/option_parser.h +++ b/src/option_parser.h @@ -42,6 +42,7 @@ enum option_dtype { OPT_BOOL, OPT_FLOAT, OPT_DOUBLE, + OPT_CHAR, OPT_CSTR }; @@ -69,6 +70,10 @@ void option_parser_cmdline(option_parser_t opp, void option_parser_cfgfile(option_parser_t opp, const char *filename); +// parse a delimited string +void option_parser_delimited_string(option_parser_t opp, + const char *inputstring, + const char *delimiters); // print options void option_parser_print(option_parser_t opp, FILE *fout); -- cgit v1.3