changeset 21fbf0412e0d in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=21fbf0412e0d
description:
        ruby: new atomics implementation

        This patch changes the way that Ruby handles atomic RMW instructions. 
This implementation, unlike the prior one, is protocol independent. It works by 
locking an address from the sequencer immediately after the read portion of an 
RMW completes. When that address is locked, the coherence controller will only 
satisfy requests coming from one port (e.g., the mandatory queue) and will 
ignore all others. After the write portion completed, the line is unlocked. 
This should also work with multi-line atomics, as long as the blocks are always 
acquired in the same order.

diffstat:

14 files changed, 59 insertions(+), 216 deletions(-)
src/mem/protocol/MESI_CMP_directory-L1cache.sm     |    6 
src/mem/protocol/MI_example-cache.sm               |    6 
src/mem/protocol/MOESI_CMP_directory-L1cache.sm    |    6 
src/mem/ruby/buffers/MessageBuffer.hh              |    5 
src/mem/ruby/config/MI_example-homogeneous.rb      |    2 
src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb   |    6 
src/mem/ruby/config/cfg.rb                         |   12 -
src/mem/ruby/libruby.cc                            |    3 
src/mem/ruby/slicc_interface/AbstractController.hh |    5 
src/mem/ruby/system/Sequencer.cc                   |   47 ------
src/mem/ruby/system/Sequencer.hh                   |    2 
src/mem/slicc/ast/PeekStatementAST.py              |   15 +
src/mem/slicc/parser.py                            |    4 
src/mem/slicc/symbols/StateMachine.py              |  156 +-------------------

diffs (truncated from 576 to 300 lines):

diff -r 3d308cbd1657 -r 21fbf0412e0d 
src/mem/protocol/MESI_CMP_directory-L1cache.sm
--- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm    Tue Jan 19 15:48:12 
2010 -0600
+++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm    Tue Jan 19 17:11:36 
2010 -0600
@@ -238,7 +238,7 @@
   // Response IntraChip L1 Network - response msg to this L1 cache
   in_port(responseIntraChipL1Network_in, ResponseMsg, responseToL1Cache) {
     if (responseIntraChipL1Network_in.isReady()) {
-      peek(responseIntraChipL1Network_in, ResponseMsg) {
+      peek(responseIntraChipL1Network_in, ResponseMsg, block_on="Address") {
         assert(in_msg.Destination.isElement(machineID));
         if(in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
           trigger(Event:Data_Exclusive, in_msg.Address);
@@ -271,7 +271,7 @@
   // Request InterChip network - request from this L1 cache to the shared L2
   in_port(requestIntraChipL1Network_in, RequestMsg, requestToL1Cache) {
     if(requestIntraChipL1Network_in.isReady()) {
-      peek(requestIntraChipL1Network_in, RequestMsg) {
+      peek(requestIntraChipL1Network_in, RequestMsg, block_on="Address") {
         assert(in_msg.Destination.isElement(machineID));
         if (in_msg.Type == CoherenceRequestType:INV) {
           trigger(Event:Inv, in_msg.Address);
@@ -292,7 +292,7 @@
   // Mandatory Queue betweens Node's CPU and it's L1 caches
   in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...") {
     if (mandatoryQueue_in.isReady()) {
-      peek(mandatoryQueue_in, CacheMsg) {
+      peek(mandatoryQueue_in, CacheMsg, block_on="LineAddress") {
 
         // Check for data access to blocks in I-cache and ifetchs to blocks in 
D-cache
 
diff -r 3d308cbd1657 -r 21fbf0412e0d src/mem/protocol/MI_example-cache.sm
--- a/src/mem/protocol/MI_example-cache.sm      Tue Jan 19 15:48:12 2010 -0600
+++ b/src/mem/protocol/MI_example-cache.sm      Tue Jan 19 17:11:36 2010 -0600
@@ -138,7 +138,7 @@
 
   in_port(forwardRequestNetwork_in, RequestMsg, forwardToCache) {
     if (forwardRequestNetwork_in.isReady()) {
-      peek(forwardRequestNetwork_in, RequestMsg) {
+      peek(forwardRequestNetwork_in, RequestMsg, block_on="Address") {
         if (in_msg.Type == CoherenceRequestType:GETX) {
           trigger(Event:Fwd_GETX, in_msg.Address);
         }
@@ -160,7 +160,7 @@
 
   in_port(responseNetwork_in, ResponseMsg, responseToCache) {
     if (responseNetwork_in.isReady()) {
-      peek(responseNetwork_in, ResponseMsg) {
+      peek(responseNetwork_in, ResponseMsg, block_on="Address") {
         if (in_msg.Type == CoherenceResponseType:DATA) {
           trigger(Event:Data, in_msg.Address);
         }
@@ -174,7 +174,7 @@
     // Mandatory Queue
   in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...") {
     if (mandatoryQueue_in.isReady()) {
-      peek(mandatoryQueue_in, CacheMsg) {
+      peek(mandatoryQueue_in, CacheMsg, block_on="LineAddress") {
 
 
         if (cacheMemory.isTagPresent(in_msg.LineAddress) == false &&
diff -r 3d308cbd1657 -r 21fbf0412e0d 
src/mem/protocol/MOESI_CMP_directory-L1cache.sm
--- a/src/mem/protocol/MOESI_CMP_directory-L1cache.sm   Tue Jan 19 15:48:12 
2010 -0600
+++ b/src/mem/protocol/MOESI_CMP_directory-L1cache.sm   Tue Jan 19 17:11:36 
2010 -0600
@@ -306,7 +306,7 @@
   // Request Network
   in_port(requestNetwork_in, RequestMsg, requestToL1Cache) {
     if (requestNetwork_in.isReady()) {
-      peek(requestNetwork_in, RequestMsg) {
+      peek(requestNetwork_in, RequestMsg, block_on="Address") {
         assert(in_msg.Destination.isElement(machineID));
         DEBUG_EXPR("MRM_DEBUG: L1 received");
         DEBUG_EXPR(in_msg.Type);
@@ -338,7 +338,7 @@
   // Response Network
   in_port(responseToL1Cache_in, ResponseMsg, responseToL1Cache) {
     if (responseToL1Cache_in.isReady()) {
-      peek(responseToL1Cache_in, ResponseMsg) {
+      peek(responseToL1Cache_in, ResponseMsg, block_on="Address") {
         if (in_msg.Type == CoherenceResponseType:ACK) {
           trigger(Event:Ack, in_msg.Address);
         } else if (in_msg.Type == CoherenceResponseType:DATA) {
@@ -356,7 +356,7 @@
   // Mandatory Queue betweens Node's CPU and it's L1 caches
   in_port(mandatoryQueue_in, CacheMsg, mandatoryQueue, desc="...") {
     if (mandatoryQueue_in.isReady()) {
-      peek(mandatoryQueue_in, CacheMsg) {
+      peek(mandatoryQueue_in, CacheMsg, block_on="LineAddress") {
 
         // Check for data access to blocks in I-cache and ifetchs to blocks in 
D-cache
 
diff -r 3d308cbd1657 -r 21fbf0412e0d src/mem/ruby/buffers/MessageBuffer.hh
--- a/src/mem/ruby/buffers/MessageBuffer.hh     Tue Jan 19 15:48:12 2010 -0600
+++ b/src/mem/ruby/buffers/MessageBuffer.hh     Tue Jan 19 17:11:36 2010 -0600
@@ -64,6 +64,11 @@
             (m_prio_heap.peekMin().m_time <= g_eventQueue_ptr->getTime()));
   }
 
+  void delayHead() {
+    MessageBufferNode node = m_prio_heap.extractMin();
+    enqueue(node.m_msgptr, 1);
+  }
+
   bool areNSlotsAvailable(int n);
   int getPriority() { return m_priority_rank; }
   void setPriority(int rank) { m_priority_rank = rank; }
diff -r 3d308cbd1657 -r 21fbf0412e0d 
src/mem/ruby/config/MI_example-homogeneous.rb
--- a/src/mem/ruby/config/MI_example-homogeneous.rb     Tue Jan 19 15:48:12 
2010 -0600
+++ b/src/mem/ruby/config/MI_example-homogeneous.rb     Tue Jan 19 17:11:36 
2010 -0600
@@ -13,7 +13,7 @@
 # default values
 
 num_cores = 2
-l1_cache_size_kb = 32768
+l1_cache_size_bytes = 32768
 l1_cache_assoc = 8
 l1_cache_latency = 1
 num_memories = 2
diff -r 3d308cbd1657 -r 21fbf0412e0d 
src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb
--- a/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb  Tue Jan 19 15:48:12 
2010 -0600
+++ b/src/mem/ruby/config/TwoLevel_SplitL1UnifiedL2.rb  Tue Jan 19 17:11:36 
2010 -0600
@@ -68,8 +68,8 @@
 require protocol+".rb"
 
 num_cores.times { |n|
-  icache = SetAssociativeCache.new("l1i_"+n.to_s, l1_icache_size_kb, 
l1_icache_latency, l1_icache_assoc, "PSEUDO_LRU")
-  dcache = SetAssociativeCache.new("l1d_"+n.to_s, l1_dcache_size_kb, 
l1_dcache_latency, l1_dcache_assoc, "PSEUDO_LRU")
+  icache = SetAssociativeCache.new("l1i_"+n.to_s, l1_icache_size_kb*1024, 
l1_icache_latency, l1_icache_assoc, "PSEUDO_LRU")
+  dcache = SetAssociativeCache.new("l1d_"+n.to_s, l1_dcache_size_kb*1024, 
l1_dcache_latency, l1_dcache_assoc, "PSEUDO_LRU")
   sequencer = Sequencer.new("Sequencer_"+n.to_s, icache, dcache)
   iface_ports << sequencer
   if protocol == "MOESI_CMP_directory"
@@ -87,7 +87,7 @@
   end
 }
 num_l2_banks.times { |n|
-  cache = SetAssociativeCache.new("l2u_"+n.to_s, 
l2_cache_size_kb/num_l2_banks, l2_cache_latency, l2_cache_assoc, "PSEUDO_LRU")
+  cache = SetAssociativeCache.new("l2u_"+n.to_s, 
(l2_cache_size_kb*1024)/num_l2_banks, l2_cache_latency, l2_cache_assoc, 
"PSEUDO_LRU")
   if protocol == "MOESI_CMP_directory"
     net_ports << 
MOESI_CMP_directory_L2CacheController.new("L2CacheController_"+n.to_s,
                                                            "L2Cache",
diff -r 3d308cbd1657 -r 21fbf0412e0d src/mem/ruby/config/cfg.rb
--- a/src/mem/ruby/config/cfg.rb        Tue Jan 19 15:48:12 2010 -0600
+++ b/src/mem/ruby/config/cfg.rb        Tue Jan 19 17:11:36 2010 -0600
@@ -385,12 +385,12 @@
 end
 
 class Cache < LibRubyObject
-  param :size_kb, Integer
+  param :size, Integer
   param :latency, Integer
   param :controller, NetPort
-  def initialize(obj_name, size_kb, latency)
+  def initialize(obj_name, size, latency)
     super(obj_name)
-    self.size_kb = size_kb
+    self.size = size
     self.latency = latency
     # controller must be set manually by the configuration script
     # because there is a cyclic dependence
@@ -406,8 +406,8 @@
   #  when an integer, it represents the number of cycles for a hit
   #  when a float, it represents the cache access time in ns
   #  when set to "auto", libruby will attempt to find a realistic latency by 
running CACTI
-  def initialize(obj_name, size_kb, latency, assoc, replacement_policy)
-    super(obj_name, size_kb, latency)
+  def initialize(obj_name, size, latency, assoc, replacement_policy)
+    super(obj_name, size, latency)
     self.assoc = assoc
     self.replacement_policy = replacement_policy
   end
@@ -415,7 +415,7 @@
   def calculateLatency()
     if self.latency == "auto"
       cacti_args = Array.new()
-      cacti_args << (self.size_kb*1024) <<  RubySystem.block_size_bytes << 
self.assoc
+      cacti_args << (self.size*1024) <<  RubySystem.block_size_bytes << 
self.assoc
       cacti_args << 1 << 0 << 0 << 0 << 1
       cacti_args << RubySystem.tech_nm << RubySystem.block_size_bytes*8
       cacti_args << 0 << 0 << 0 << 1 << 0 << 0 << 0 << 0 << 1
diff -r 3d308cbd1657 -r 21fbf0412e0d src/mem/ruby/libruby.cc
--- a/src/mem/ruby/libruby.cc   Tue Jan 19 15:48:12 2010 -0600
+++ b/src/mem/ruby/libruby.cc   Tue Jan 19 17:11:36 2010 -0600
@@ -58,11 +58,8 @@
 
 ostream& operator<<(ostream& out, const RubyRequestType& obj)
 {
-  cerr << "in op" << endl;
   out << RubyRequestType_to_string(obj);
-  cerr << "flushing" << endl;
   out << flush;
-  cerr << "done" << endl;
   return out;
 }
 
diff -r 3d308cbd1657 -r 21fbf0412e0d 
src/mem/ruby/slicc_interface/AbstractController.hh
--- a/src/mem/ruby/slicc_interface/AbstractController.hh        Tue Jan 19 
15:48:12 2010 -0600
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh        Tue Jan 19 
17:11:36 2010 -0600
@@ -21,9 +21,8 @@
   virtual const string toString() const = 0;  // returns text version of 
controller type
   virtual const string getName() const = 0;   // return instance name
   virtual const MachineType getMachineType() const = 0;
-  virtual void set_atomic(Address addr) = 0;
-  virtual void clear_atomic(Address addr) = 0;
-  virtual void reset_atomics() = 0;
+  virtual void blockOnQueue(Address, MessageBuffer*) = 0;
+  virtual void unblock(Address) = 0;
 
   virtual void print(ostream & out) const = 0;
   virtual void printStats(ostream & out) const = 0;
diff -r 3d308cbd1657 -r 21fbf0412e0d src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc  Tue Jan 19 15:48:12 2010 -0600
+++ b/src/mem/ruby/system/Sequencer.cc  Tue Jan 19 17:11:36 2010 -0600
@@ -66,8 +66,6 @@
   m_instCache_ptr = NULL;
   m_dataCache_ptr = NULL;
   m_controller = NULL;
-  m_atomic_reads = 0;
-  m_atomic_writes = 0;
   for (size_t i=0; i<argv.size(); i+=2) {
     if ( argv[i] == "controller") {
       m_controller = RubySystem::getController(argv[i+1]); // args[i] = 
"L1Cache"
@@ -285,15 +283,15 @@
          (request->ruby_request.type == RubyRequestType_RMW_Write) ||  
          (request->ruby_request.type == RubyRequestType_Locked_Read) ||
          (request->ruby_request.type == RubyRequestType_Locked_Write));
-  // POLINA: the assumption is that atomics are only on data cache and not 
instruction cache
+
   if (request->ruby_request.type == RubyRequestType_Locked_Read) {
     m_dataCache_ptr->setLocked(address, m_version);
   }
   else if (request->ruby_request.type == RubyRequestType_RMW_Read) {
-    m_controller->set_atomic(address);
+    m_controller->blockOnQueue(address, m_mandatory_q_ptr);
   }
   else if (request->ruby_request.type == RubyRequestType_RMW_Write) {
-    m_controller->clear_atomic(address);
+    m_controller->unblock(address);
   }
 
   hitCallback(request, data);
@@ -438,42 +436,12 @@
   CacheRequestType ctype;
   switch(request.type) {
   case RubyRequestType_IFETCH:
-    if (m_atomic_reads > 0 && m_atomic_writes == 0) {
-      m_controller->reset_atomics();
-      m_atomic_writes = 0;
-      m_atomic_reads = 0;
-    }
-    else if (m_atomic_writes > 0) {
-      assert(m_atomic_reads > m_atomic_writes);
-      cerr << "WARNING: Expected: " << m_atomic_reads << " RMW_Writes, but 
only received: " << m_atomic_writes << endl;
-      assert(false);
-    }
     ctype = CacheRequestType_IFETCH;
     break;
   case RubyRequestType_LD:
-    if (m_atomic_reads > 0 && m_atomic_writes == 0) {
-      m_controller->reset_atomics();
-      m_atomic_writes = 0;
-      m_atomic_reads = 0;
-    }
-    else if (m_atomic_writes > 0) {
-      assert(m_atomic_reads > m_atomic_writes);
-      cerr << "WARNING: Expected: " << m_atomic_reads << " RMW_Writes, but 
only received: " << m_atomic_writes << endl;
-      assert(false);
-    }
     ctype = CacheRequestType_LD;
     break;
   case RubyRequestType_ST:
-    if (m_atomic_reads > 0 && m_atomic_writes == 0) {
-      m_controller->reset_atomics();
-      m_atomic_writes = 0;
-      m_atomic_reads = 0;
-    }
-    else if (m_atomic_writes > 0) {
-      assert(m_atomic_reads > m_atomic_writes);
-      cerr << "WARNING: Expected: " << m_atomic_reads << " RMW_Writes, but 
only received: " << m_atomic_writes << endl;
-      assert(false);
-    }
     ctype = CacheRequestType_ST;
     break;
   case RubyRequestType_Locked_Read:
@@ -481,18 +449,9 @@
     ctype = CacheRequestType_ATOMIC;
     break;
   case RubyRequestType_RMW_Read:
-    assert(m_atomic_writes == 0);
-    m_atomic_reads++;
     ctype = CacheRequestType_ATOMIC;
     break;
   case RubyRequestType_RMW_Write:
-    assert(m_atomic_reads > 0);
-    assert(m_atomic_writes < m_atomic_reads);
-    m_atomic_writes++;
-    if (m_atomic_reads == m_atomic_writes) {
-      m_atomic_reads = 0;
-      m_atomic_writes = 0;
-    }
     ctype = CacheRequestType_ATOMIC;
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to