cpu: Add support for protobuf input for the trace generator

This patch adds support for reading input traces encoded using
protobuf according to what is done in the CommMonitor.

A follow-up patch adds a Python script that can be used to convert the
previously used ASCII traces to protobuf equivalents. The appropriate
regression input is updated as part of this patch.
This commit is contained in:
Andreas Hansson 2013-01-07 13:05:37 -05:00
parent 9c5ef235cc
commit 1da209140c
6 changed files with 38 additions and 62 deletions

View file

@ -39,6 +39,9 @@
Import('*') Import('*')
# Only build the traffic generator if we have support for protobuf as the
# tracing relies on it
if env['HAVE_PROTOBUF']:
SimObject('TrafficGen.py') SimObject('TrafficGen.py')
Source('traffic_gen.cc') Source('traffic_gen.cc')

View file

@ -45,6 +45,7 @@
#include "cpu/testers/traffic_gen/traffic_gen.hh" #include "cpu/testers/traffic_gen/traffic_gen.hh"
#include "debug/Checkpoint.hh" #include "debug/Checkpoint.hh"
#include "debug/TrafficGen.hh" #include "debug/TrafficGen.hh"
#include "proto/packet.pb.h"
#include "sim/stats.hh" #include "sim/stats.hh"
#include "sim/system.hh" #include "sim/system.hh"
@ -497,65 +498,35 @@ TrafficGen::StateGraph::RandomGen::nextExecuteTick()
TrafficGen::StateGraph::TraceGen::InputStream::InputStream(const string& TrafficGen::StateGraph::TraceGen::InputStream::InputStream(const string&
filename) filename)
: trace(filename)
{ {
trace.rdbuf()->pubsetbuf(readBuffer, 4 * 1024 * 1024); // Create a protobuf message for the header and read it from the stream
trace.open(filename.c_str(), ifstream::in); Message::PacketHeader header_msg;
if (!trace.read(header_msg)) {
panic("Failed to read packet header from %s\n", filename);
if (!trace.is_open()) { if (header_msg.tick_freq() != SimClock::Frequency) {
fatal("Traffic generator trace file could not be" panic("Trace %s was recorded with a different tick frequency %d\n",
" opened: %s\n", filename); header_msg.tick_freq());
}
} }
} }
void void
TrafficGen::StateGraph::TraceGen::InputStream::reset() TrafficGen::StateGraph::TraceGen::InputStream::reset()
{ {
// seek to the start of the input trace file trace.reset();
trace.seekg(0, ifstream::beg);
trace.clear();
} }
bool bool
TrafficGen::StateGraph::TraceGen::InputStream::read(TraceElement& element) TrafficGen::StateGraph::TraceGen::InputStream::read(TraceElement& element)
{ {
string buffer; Message::Packet pkt_msg;
bool format_error = false; if (trace.read(pkt_msg)) {
assert(trace.good()); element.cmd = pkt_msg.cmd();
getline(trace, buffer); element.addr = pkt_msg.addr();
element.blocksize = pkt_msg.size();
// Check that we have something to process. This assumes no EOF at element.tick = pkt_msg.tick();
// the end of the line.
if (buffer.size() > 0 && !trace.eof()) {
std::istringstream iss(buffer);
char rOrW, ch;
iss >> rOrW;
if (rOrW == 'r') {
element.cmd = MemCmd::ReadReq;
} else if (rOrW == 'w') {
element.cmd = MemCmd::WriteReq;
} else {
format_error = true;
}
// eat a comma, then get the address
iss >> ch;
format_error |= ch != ',';
iss >> element.addr;
// eat a comma, then get the blocksize
iss >> ch;
format_error |= ch != ',';
iss >> element.blocksize;
// eat a comma, then get the tick
iss >> ch;
format_error |= ch != ',';
iss >> element.tick;
if (format_error)
fatal("Trace format error in %s\n", buffer);
return true; return true;
} }

View file

@ -41,12 +41,11 @@
#ifndef __MEM_TRAFFIC_GEN_HH__ #ifndef __MEM_TRAFFIC_GEN_HH__
#define __MEM_TRAFFIC_GEN_HH__ #define __MEM_TRAFFIC_GEN_HH__
#include <fstream>
#include "base/hashmap.hh" #include "base/hashmap.hh"
#include "mem/mem_object.hh" #include "mem/mem_object.hh"
#include "mem/qport.hh" #include "mem/qport.hh"
#include "params/TrafficGen.hh" #include "params/TrafficGen.hh"
#include "proto/protoio.hh"
/** /**
* The traffic generator is a master module that generates stimuli for * The traffic generator is a master module that generates stimuli for
@ -449,15 +448,8 @@ class TrafficGen : public MemObject
private: private:
/// Input file stream for the ASCII trace /// Input file stream for the protobuf trace
std::ifstream trace; ProtoInputStream trace;
/**
* Create a 4MB read buffer for the input trace
* file. This is to reduce the number of disk accesses
* and thereby speed up the execution.
*/
char readBuffer[4 * 1024 * 1024];
public: public:

View file

@ -38,6 +38,11 @@
import m5 import m5
from m5.objects import * from m5.objects import *
# both traffic generator and communication monitor are only available
# if we have protobuf support, so potentially skip this test
require_sim_object("TrafficGen")
require_sim_object("CommMonitor")
# even if this is only a traffic generator, call it cpu to make sure # even if this is only a traffic generator, call it cpu to make sure
# the scripts are happy # the scripts are happy
cpu = TrafficGen(config_file = "tests/quick/se/70.tgen/tgen-simple-dram.cfg") cpu = TrafficGen(config_file = "tests/quick/se/70.tgen/tgen-simple-dram.cfg")

View file

@ -38,6 +38,11 @@
import m5 import m5
from m5.objects import * from m5.objects import *
# both traffic generator and communication monitor are only available
# if we have protobuf support, so potentially skip this test
require_sim_object("TrafficGen")
require_sim_object("CommMonitor")
# even if this is only a traffic generator, call it cpu to make sure # even if this is only a traffic generator, call it cpu to make sure
# the scripts are happy # the scripts are happy
cpu = TrafficGen(config_file = "tests/quick/se/70.tgen/tgen-simple-mem.cfg") cpu = TrafficGen(config_file = "tests/quick/se/70.tgen/tgen-simple-mem.cfg")

View file

@ -1,2 +1,2 @@
r,19088743,64,1000 gem51
w,48879,64,4000 )Converted ASCII trace tgen-simple-mem.trc€”ëÜ èçŠ<C3A7> @  ïý @