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('*')
# Only build the traffic generator if we have support for protobuf as the
# tracing relies on it
if env['HAVE_PROTOBUF']:
SimObject('TrafficGen.py')
Source('traffic_gen.cc')

View file

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

View file

@ -41,12 +41,11 @@
#ifndef __MEM_TRAFFIC_GEN_HH__
#define __MEM_TRAFFIC_GEN_HH__
#include <fstream>
#include "base/hashmap.hh"
#include "mem/mem_object.hh"
#include "mem/qport.hh"
#include "params/TrafficGen.hh"
#include "proto/protoio.hh"
/**
* The traffic generator is a master module that generates stimuli for
@ -449,15 +448,8 @@ class TrafficGen : public MemObject
private:
/// Input file stream for the ASCII trace
std::ifstream 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];
/// Input file stream for the protobuf trace
ProtoInputStream trace;
public:

View file

@ -38,6 +38,11 @@
import m5
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
# the scripts are happy
cpu = TrafficGen(config_file = "tests/quick/se/70.tgen/tgen-simple-dram.cfg")

View file

@ -38,6 +38,11 @@
import m5
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
# the scripts are happy
cpu = TrafficGen(config_file = "tests/quick/se/70.tgen/tgen-simple-mem.cfg")

View file

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