summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2013-07-18 08:31:16 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2013-07-18 08:31:16 -0400
commitd4273cc9a6f3c00566e97ebcd71509ed14477b37 (patch)
tree9b50625fc5d2bb457a959f379a45687903660237 /src/mem
parent4e8ecd7c6fd0447f563179b5a8fdbb13b562ca9e (diff)
downloadgem5-d4273cc9a6f3c00566e97ebcd71509ed14477b37.tar.xz
mem: Set the cache line size on a system level
This patch removes the notion of a peer block size and instead sets the cache line size on the system level. Previously the size was set per cache, and communicated through the interconnect. There were plenty checks to ensure that everyone had the same size specified, and these checks are now removed. Another benefit that is not yet harnessed is that the cache line size is now known at construction time, rather than after the port binding. Hence, the block size can be locally stored and does not have to be queried every time it is used. A follow-on patch updates the configuration scripts accordingly.
Diffstat (limited to 'src/mem')
-rw-r--r--src/mem/Bus.py2
-rw-r--r--src/mem/SimpleDRAM.py2
-rw-r--r--src/mem/addr_mapper.cc18
-rw-r--r--src/mem/addr_mapper.hh14
-rw-r--r--src/mem/bridge.cc5
-rw-r--r--src/mem/bus.cc32
-rw-r--r--src/mem/bus.hh11
-rw-r--r--src/mem/cache/BaseCache.py1
-rw-r--r--src/mem/cache/base.cc4
-rw-r--r--src/mem/cache/cache.hh6
-rw-r--r--src/mem/cache/tags/Tags.py4
-rw-r--r--src/mem/coherent_bus.hh12
-rw-r--r--src/mem/comm_monitor.cc12
-rw-r--r--src/mem/comm_monitor.hh14
-rw-r--r--src/mem/fs_translating_port_proxy.cc11
-rw-r--r--src/mem/fs_translating_port_proxy.hh2
-rw-r--r--src/mem/noncoherent_bus.hh12
-rw-r--r--src/mem/port.cc12
-rw-r--r--src/mem/port.hh22
-rw-r--r--src/mem/port_proxy.cc2
-rw-r--r--src/mem/port_proxy.hh8
-rw-r--r--src/mem/ruby/system/RubyPort.cc6
-rw-r--r--src/mem/ruby/system/RubyPort.hh1
-rw-r--r--src/mem/se_translating_port_proxy.cc5
-rw-r--r--src/mem/simple_dram.cc3
25 files changed, 26 insertions, 195 deletions
diff --git a/src/mem/Bus.py b/src/mem/Bus.py
index ca0f40e1e..e8e03ccb4 100644
--- a/src/mem/Bus.py
+++ b/src/mem/Bus.py
@@ -52,8 +52,6 @@ class BaseBus(MemObject):
master = VectorMasterPort("vector port for connecting slaves")
header_cycles = Param.Cycles(1, "cycles of overhead per transaction")
width = Param.Unsigned(8, "bus width (bytes)")
- block_size = Param.Unsigned(64, "The default block size if not set by " \
- "any connected module")
# The default port can be left unconnected, or be used to connect
# a default slave port
diff --git a/src/mem/SimpleDRAM.py b/src/mem/SimpleDRAM.py
index 64e9f272b..ec76542d8 100644
--- a/src/mem/SimpleDRAM.py
+++ b/src/mem/SimpleDRAM.py
@@ -170,7 +170,7 @@ class SimpleDRAM(AbstractMemory):
# tRC - assumed to be 4 * tRP
- # burst length for an access derived from peerBlockSize
+ # burst length for an access derived from the cache line size
# A single DDR3 x64 interface (one command and address bus), with
# default timings based on DDR3-1600 4 Gbit parts in an 8x8
diff --git a/src/mem/addr_mapper.cc b/src/mem/addr_mapper.cc
index 4aff9dcd8..0cc2e9c2f 100644
--- a/src/mem/addr_mapper.cc
+++ b/src/mem/addr_mapper.cc
@@ -51,12 +51,6 @@ AddrMapper::init()
{
if (!slavePort.isConnected() || !masterPort.isConnected())
fatal("Address mapper is not connected on both sides.\n");
-
- if ((slavePort.peerBlockSize() != masterPort.peerBlockSize()) &&
- slavePort.peerBlockSize() && masterPort.peerBlockSize())
- fatal("Slave port size %d, master port size %d \n "
- "don't have the same block size... Not supported.\n",
- slavePort.peerBlockSize(), masterPort.peerBlockSize());
}
BaseMasterPort&
@@ -195,18 +189,6 @@ AddrMapper::isSnooping() const
return false;
}
-unsigned
-AddrMapper::deviceBlockSizeMaster()
-{
- return slavePort.peerBlockSize();
-}
-
-unsigned
-AddrMapper::deviceBlockSizeSlave()
-{
- return masterPort.peerBlockSize();
-}
-
void
AddrMapper::recvRetryMaster()
{
diff --git a/src/mem/addr_mapper.hh b/src/mem/addr_mapper.hh
index 6604096bd..6564a7490 100644
--- a/src/mem/addr_mapper.hh
+++ b/src/mem/addr_mapper.hh
@@ -143,11 +143,6 @@ class AddrMapper : public MemObject
return mapper.isSnooping();
}
- unsigned deviceBlockSize() const
- {
- return mapper.deviceBlockSizeMaster();
- }
-
void recvRetry()
{
mapper.recvRetryMaster();
@@ -193,11 +188,6 @@ class AddrMapper : public MemObject
return mapper.recvTimingSnoopResp(pkt);
}
- unsigned deviceBlockSize() const
- {
- return mapper.deviceBlockSizeSlave();
- }
-
AddrRangeList getAddrRanges() const
{
return mapper.getAddrRanges();
@@ -233,10 +223,6 @@ class AddrMapper : public MemObject
bool recvTimingSnoopResp(PacketPtr pkt);
- unsigned deviceBlockSizeMaster();
-
- unsigned deviceBlockSizeSlave();
-
virtual AddrRangeList getAddrRanges() const = 0;
bool isSnooping() const;
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index f8258086c..3b101ceab 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -110,11 +110,6 @@ Bridge::init()
if (!slavePort.isConnected() || !masterPort.isConnected())
fatal("Both ports of bus bridge are not connected to a bus.\n");
- if (slavePort.peerBlockSize() != masterPort.peerBlockSize())
- fatal("Slave port size %d, master port size %d \n " \
- "Busses don't have the same block size... Not supported.\n",
- slavePort.peerBlockSize(), masterPort.peerBlockSize());
-
// notify the master side of our address ranges
slavePort.sendRangeChange();
}
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index d94bd6a28..5ab7e5b04 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -60,8 +60,7 @@ BaseBus::BaseBus(const BaseBusParams *p)
gotAddrRanges(p->port_default_connection_count +
p->port_master_connection_count, false),
gotAllAddrRanges(false), defaultPortID(InvalidPortID),
- useDefaultRange(p->use_default_range),
- blockSize(p->block_size)
+ useDefaultRange(p->use_default_range)
{}
BaseBus::~BaseBus()
@@ -80,29 +79,6 @@ BaseBus::~BaseBus()
void
BaseBus::init()
{
- // determine the maximum peer block size, look at both the
- // connected master and slave modules
- uint32_t peer_block_size = 0;
-
- for (MasterPortConstIter m = masterPorts.begin(); m != masterPorts.end();
- ++m) {
- peer_block_size = std::max((*m)->peerBlockSize(), peer_block_size);
- }
-
- for (SlavePortConstIter s = slavePorts.begin(); s != slavePorts.end();
- ++s) {
- peer_block_size = std::max((*s)->peerBlockSize(), peer_block_size);
- }
-
- // if the peers do not have a block size, use the default value
- // set through the bus parameters
- if (peer_block_size != 0)
- blockSize = peer_block_size;
-
- // check if the block size is a value known to work
- if (!(blockSize == 16 || blockSize == 32 || blockSize == 64 ||
- blockSize == 128))
- warn_once("Block size is neither 16, 32, 64 or 128 bytes.\n");
}
BaseMasterPort &
@@ -559,12 +535,6 @@ BaseBus::getAddrRanges() const
return busRanges;
}
-unsigned
-BaseBus::deviceBlockSize() const
-{
- return blockSize;
-}
-
void
BaseBus::regStats()
{
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index fc240a22b..bdcf319f4 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -345,15 +345,6 @@ class BaseBus : public MemObject
void calcPacketTiming(PacketPtr pkt);
/**
- * Ask everyone on the bus what their size is and determine the
- * bus size as either the maximum, or if no device specifies a
- * block size return the default.
- *
- * @return the max of all the sizes or the default if none is set
- */
- unsigned deviceBlockSize() const;
-
- /**
* Remember for each of the master ports of the bus if we got an
* address range from the connected slave. For convenience, also
* keep track of if we got ranges from all the slave modules or
@@ -381,8 +372,6 @@ class BaseBus : public MemObject
addresses not handled by another port to default device. */
const bool useDefaultRange;
- uint32_t blockSize;
-
BaseBus(const BaseBusParams *p);
virtual ~BaseBus();
diff --git a/src/mem/cache/BaseCache.py b/src/mem/cache/BaseCache.py
index 7f2c1cc6f..df4602199 100644
--- a/src/mem/cache/BaseCache.py
+++ b/src/mem/cache/BaseCache.py
@@ -48,7 +48,6 @@ class BaseCache(MemObject):
type = 'BaseCache'
cxx_header = "mem/cache/base.hh"
assoc = Param.Int("associativity")
- block_size = Param.Int("block size in bytes")
hit_latency = Param.Cycles("The hit latency for this cache")
response_latency = Param.Cycles(
"Additional cache latency for the return path to core on a miss");
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index 62f1bb21b..03b4d5dc1 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -71,7 +71,7 @@ BaseCache::BaseCache(const Params *p)
mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
MSHRQueue_WriteBuffer),
- blkSize(p->block_size),
+ blkSize(p->system->cacheLineSize()),
hitLatency(p->hit_latency),
responseLatency(p->response_latency),
numTarget(p->tgts_per_mshr),
@@ -773,7 +773,7 @@ BaseCache::drain(DrainManager *dm)
BaseCache *
BaseCacheParams::create()
{
- unsigned numSets = size / (assoc * block_size);
+ unsigned numSets = size / (assoc * system->cacheLineSize());
assert(tags);
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 729e1f32c..ab884372c 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -99,9 +99,6 @@ class Cache : public BaseCache
virtual void recvFunctional(PacketPtr pkt);
- virtual unsigned deviceBlockSize() const
- { return cache->getBlockSize(); }
-
virtual AddrRangeList getAddrRanges() const;
public:
@@ -163,9 +160,6 @@ class Cache : public BaseCache
virtual void recvFunctionalSnoop(PacketPtr pkt);
- virtual unsigned deviceBlockSize() const
- { return cache->getBlockSize(); }
-
public:
MemSidePort(const std::string &_name, Cache<TagStore> *_cache,
diff --git a/src/mem/cache/tags/Tags.py b/src/mem/cache/tags/Tags.py
index c1aad2444..c5beff4a7 100644
--- a/src/mem/cache/tags/Tags.py
+++ b/src/mem/cache/tags/Tags.py
@@ -46,8 +46,8 @@ class BaseTags(ClockedObject):
# Get the size from the parent (cache)
size = Param.MemorySize(Parent.size, "capacity in bytes")
- # Get the block size from the parent (cache)
- block_size = Param.Int(Parent.block_size, "block size in bytes")
+ # Get the block size from the parent (system)
+ block_size = Param.Int(Parent.cache_line_size, "block size in bytes")
# Get the hit latency from the parent (cache)
hit_latency = Param.Cycles(Parent.hit_latency,
diff --git a/src/mem/coherent_bus.hh b/src/mem/coherent_bus.hh
index 4908ba034..034b855ec 100644
--- a/src/mem/coherent_bus.hh
+++ b/src/mem/coherent_bus.hh
@@ -140,12 +140,6 @@ class CoherentBus : public BaseBus
virtual AddrRangeList getAddrRanges() const
{ return bus.getAddrRanges(); }
- /**
- * Get the maximum block size as seen by the bus.
- */
- virtual unsigned deviceBlockSize() const
- { return bus.deviceBlockSize(); }
-
};
/**
@@ -211,12 +205,6 @@ class CoherentBus : public BaseBus
virtual void recvRetry()
{ bus.recvRetry(id); }
- // Ask the bus to ask everyone on the bus what their block size is and
- // take the max of it. This might need to be changed a bit if we ever
- // support multiple block sizes.
- virtual unsigned deviceBlockSize() const
- { return bus.deviceBlockSize(); }
-
};
/**
diff --git a/src/mem/comm_monitor.cc b/src/mem/comm_monitor.cc
index 562f572d8..5db6f5e9a 100644
--- a/src/mem/comm_monitor.cc
+++ b/src/mem/comm_monitor.cc
@@ -378,18 +378,6 @@ CommMonitor::isSnooping() const
return slavePort.isSnooping();
}
-unsigned
-CommMonitor::deviceBlockSizeMaster()
-{
- return slavePort.peerBlockSize();
-}
-
-unsigned
-CommMonitor::deviceBlockSizeSlave()
-{
- return masterPort.peerBlockSize();
-}
-
AddrRangeList
CommMonitor::getAddrRanges() const
{
diff --git a/src/mem/comm_monitor.hh b/src/mem/comm_monitor.hh
index d386eeba0..9dcd065ca 100644
--- a/src/mem/comm_monitor.hh
+++ b/src/mem/comm_monitor.hh
@@ -171,11 +171,6 @@ class CommMonitor : public MemObject
return mon.isSnooping();
}
- unsigned deviceBlockSize() const
- {
- return mon.deviceBlockSizeMaster();
- }
-
void recvRetry()
{
mon.recvRetryMaster();
@@ -227,11 +222,6 @@ class CommMonitor : public MemObject
return mon.recvTimingSnoopResp(pkt);
}
- unsigned deviceBlockSize() const
- {
- return mon.deviceBlockSizeSlave();
- }
-
AddrRangeList getAddrRanges() const
{
return mon.getAddrRanges();
@@ -267,10 +257,6 @@ class CommMonitor : public MemObject
bool recvTimingSnoopResp(PacketPtr pkt);
- unsigned deviceBlockSizeMaster();
-
- unsigned deviceBlockSizeSlave();
-
AddrRangeList getAddrRanges() const;
bool isSnooping() const;
diff --git a/src/mem/fs_translating_port_proxy.cc b/src/mem/fs_translating_port_proxy.cc
index 9f1f7d019..8fb9b91ef 100644
--- a/src/mem/fs_translating_port_proxy.cc
+++ b/src/mem/fs_translating_port_proxy.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 ARM Limited
+ * Copyright (c) 2011,2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -50,16 +50,19 @@
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "mem/fs_translating_port_proxy.hh"
+#include "sim/system.hh"
using namespace TheISA;
FSTranslatingPortProxy::FSTranslatingPortProxy(ThreadContext *tc)
- : PortProxy(tc->getCpuPtr()->getDataPort()), _tc(tc)
+ : PortProxy(tc->getCpuPtr()->getDataPort(),
+ tc->getSystemPtr()->cacheLineSize()), _tc(tc)
{
}
-FSTranslatingPortProxy::FSTranslatingPortProxy(MasterPort &port)
- : PortProxy(port), _tc(NULL)
+FSTranslatingPortProxy::FSTranslatingPortProxy(MasterPort &port,
+ unsigned int cacheLineSize)
+ : PortProxy(port, cacheLineSize), _tc(NULL)
{
}
diff --git a/src/mem/fs_translating_port_proxy.hh b/src/mem/fs_translating_port_proxy.hh
index c022f3d09..2a9223050 100644
--- a/src/mem/fs_translating_port_proxy.hh
+++ b/src/mem/fs_translating_port_proxy.hh
@@ -78,7 +78,7 @@ class FSTranslatingPortProxy : public PortProxy
FSTranslatingPortProxy(ThreadContext* tc);
- FSTranslatingPortProxy(MasterPort &port);
+ FSTranslatingPortProxy(MasterPort &port, unsigned int cacheLineSize);
virtual ~FSTranslatingPortProxy();
diff --git a/src/mem/noncoherent_bus.hh b/src/mem/noncoherent_bus.hh
index e2148c60e..a1b9da6e3 100644
--- a/src/mem/noncoherent_bus.hh
+++ b/src/mem/noncoherent_bus.hh
@@ -132,12 +132,6 @@ class NoncoherentBus : public BaseBus
virtual AddrRangeList getAddrRanges() const
{ return bus.getAddrRanges(); }
- /**
- * Get the maximum block size as seen by the bus.
- */
- virtual unsigned deviceBlockSize() const
- { return bus.deviceBlockSize(); }
-
};
/**
@@ -177,12 +171,6 @@ class NoncoherentBus : public BaseBus
virtual void recvRetry()
{ bus.recvRetry(id); }
- /**
- * Get the maximum block size as seen by the bus.
- */
- virtual unsigned deviceBlockSize() const
- { return bus.deviceBlockSize(); }
-
};
/** Function called by the port when the bus is recieving a Timing
diff --git a/src/mem/port.cc b/src/mem/port.cc
index 45045f40e..898f19c08 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -155,12 +155,6 @@ MasterPort::unbind()
_baseSlavePort = NULL;
}
-unsigned
-MasterPort::peerBlockSize() const
-{
- return _slavePort->deviceBlockSize();
-}
-
AddrRangeList
MasterPort::getAddrRanges() const
{
@@ -238,12 +232,6 @@ SlavePort::bind(MasterPort& master_port)
_masterPort = &master_port;
}
-unsigned
-SlavePort::peerBlockSize() const
-{
- return _masterPort->deviceBlockSize();
-}
-
Tick
SlavePort::sendAtomicSnoop(PacketPtr pkt)
{
diff --git a/src/mem/port.hh b/src/mem/port.hh
index 18db800b6..8fefb2f3a 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -265,17 +265,6 @@ class MasterPort : public BaseMasterPort
virtual bool isSnooping() const { return false; }
/**
- * Called by a peer port in order to determine the block size of
- * the owner of this port.
- */
- virtual unsigned deviceBlockSize() const { return 0; }
-
- /** Called by the associated device if it wishes to find out the blocksize
- of the device on attached to the peer port.
- */
- unsigned peerBlockSize() const;
-
- /**
* Get the address ranges of the connected slave port.
*/
AddrRangeList getAddrRanges() const;
@@ -406,17 +395,6 @@ class SlavePort : public BaseSlavePort
void sendRetry();
/**
- * Called by a peer port in order to determine the block size of
- * the owner of this port.
- */
- virtual unsigned deviceBlockSize() const { return 0; }
-
- /** Called by the associated device if it wishes to find out the blocksize
- of the device on attached to the peer port.
- */
- unsigned peerBlockSize() const;
-
- /**
* Find out if the peer master port is snooping or not.
*
* @return true if the peer master port is snooping
diff --git a/src/mem/port_proxy.cc b/src/mem/port_proxy.cc
index 38162e1bf..ea6dd0fc2 100644
--- a/src/mem/port_proxy.cc
+++ b/src/mem/port_proxy.cc
@@ -45,7 +45,7 @@ PortProxy::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd) const
{
Request req;
- for (ChunkGenerator gen(addr, size, _port.peerBlockSize());
+ for (ChunkGenerator gen(addr, size, _cacheLineSize);
!gen.done(); gen.next()) {
req.setPhys(gen.addr(), gen.size(), 0, Request::funcMasterId);
Packet pkt(&req, cmd);
diff --git a/src/mem/port_proxy.hh b/src/mem/port_proxy.hh
index 4600cd407..f1e01c385 100644
--- a/src/mem/port_proxy.hh
+++ b/src/mem/port_proxy.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012 ARM Limited
+ * Copyright (c) 2011-2013 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -88,10 +88,14 @@ class PortProxy
/** The actual physical port used by this proxy. */
MasterPort &_port;
+ /** Granularity of any transactions issued through this proxy. */
+ const unsigned int _cacheLineSize;
+
void blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd) const;
public:
- PortProxy(MasterPort &port) : _port(port) { }
+ PortProxy(MasterPort &port, unsigned int cacheLineSize) :
+ _port(port), _cacheLineSize(cacheLineSize) { }
virtual ~PortProxy() { }
/**
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index 72dc1447a..719e2f73f 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -476,12 +476,6 @@ RubyPort::M5Port::isPhysMemAddress(Addr addr)
return ruby_port->system->isMemAddr(addr);
}
-unsigned
-RubyPort::M5Port::deviceBlockSize() const
-{
- return (unsigned) RubySystem::getBlockSizeBytes();
-}
-
void
RubyPort::ruby_eviction_callback(const Address& address)
{
diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh
index 70f74d83b..1e9336d76 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -73,7 +73,6 @@ class RubyPort : public MemObject
RubySystem*_system, bool _access_phys_mem);
void hitCallback(PacketPtr pkt);
void evictionCallback(const Address& address);
- unsigned deviceBlockSize() const;
bool onRetryList()
{ return _onRetryList; }
diff --git a/src/mem/se_translating_port_proxy.cc b/src/mem/se_translating_port_proxy.cc
index 7857217f6..1060a3270 100644
--- a/src/mem/se_translating_port_proxy.cc
+++ b/src/mem/se_translating_port_proxy.cc
@@ -50,13 +50,14 @@
#include "mem/page_table.hh"
#include "mem/se_translating_port_proxy.hh"
#include "sim/process.hh"
+#include "sim/system.hh"
using namespace TheISA;
SETranslatingPortProxy::SETranslatingPortProxy(MasterPort& port, Process *p,
AllocType alloc)
- : PortProxy(port), pTable(p->pTable), process(p),
- allocating(alloc)
+ : PortProxy(port, p->system->cacheLineSize()), pTable(p->pTable),
+ process(p), allocating(alloc)
{ }
SETranslatingPortProxy::~SETranslatingPortProxy()
diff --git a/src/mem/simple_dram.cc b/src/mem/simple_dram.cc
index bd3a70d25..2bb1cec9d 100644
--- a/src/mem/simple_dram.cc
+++ b/src/mem/simple_dram.cc
@@ -43,6 +43,7 @@
#include "debug/DRAM.hh"
#include "debug/DRAMWR.hh"
#include "mem/simple_dram.hh"
+#include "sim/system.hh"
using namespace std;
@@ -94,7 +95,7 @@ SimpleDRAM::init()
// get the burst size from the connected port as it is currently
// assumed to be equal to the cache line size
- bytesPerCacheLine = port.peerBlockSize();
+ bytesPerCacheLine = _system->cacheLineSize();
// we could deal with plenty options here, but for now do a quick
// sanity check