ruby: get rid of PrioHeap and use STL
authorNathan Binkert <nate@binkert.org>
Fri, 11 Jun 2010 06:17:07 +0000 (23:17 -0700)
committerNathan Binkert <nate@binkert.org>
Fri, 11 Jun 2010 06:17:07 +0000 (23:17 -0700)
One big difference is that PrioHeap puts the smallest element at the
top of the heap, whereas stl puts the largest element on top, so I
changed all comparisons so they did the right thing.

Some usage of PrioHeap was simply changed to a std::vector, using sort
at the right time, other usage had me just use the various heap functions
in the stl.

23 files changed:
src/mem/gems_common/PrioHeap.hh [deleted file]
src/mem/ruby/buffers/MessageBuffer.cc
src/mem/ruby/buffers/MessageBuffer.hh
src/mem/ruby/buffers/MessageBufferNode.hh
src/mem/ruby/eventqueue/RubyEventQueue.hh
src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh
src/mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh
src/mem/ruby/network/garnet/fixed-pipeline/flit_d.hh
src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh
src/mem/ruby/network/garnet/flexible-pipeline/Router.hh
src/mem/ruby/network/garnet/flexible-pipeline/flit.hh
src/mem/ruby/network/garnet/flexible-pipeline/flitBuffer.cc
src/mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh
src/mem/ruby/profiler/AccessTraceForAddress.hh
src/mem/ruby/profiler/AddressProfiler.cc
src/mem/ruby/profiler/CacheProfiler.cc
src/mem/ruby/profiler/Profiler.cc
src/mem/ruby/recorder/CacheRecorder.cc
src/mem/ruby/recorder/CacheRecorder.hh
src/mem/ruby/recorder/TraceRecord.hh
src/mem/ruby/recorder/Tracer.cc
src/mem/ruby/recorder/Tracer.hh

diff --git a/src/mem/gems_common/PrioHeap.hh b/src/mem/gems_common/PrioHeap.hh
deleted file mode 100644 (file)
index 266d35e..0000000
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PRIOHEAP_H
-#define PRIOHEAP_H
-
-#include <cassert>
-#include <iostream>
-#include <vector>
-
-typedef unsigned int HeapIndex;
-
-template <class TYPE>
-class PrioHeap {
-public:
-  // Constructors
-  PrioHeap() { init(); }
-
-  // Destructor
-  //~PrioHeap();
-
-  // Public Methods
-  void init() { m_current_size = 0; }
-  int size() const { return m_current_size; }
-  void insert(const TYPE& key);
-  const TYPE& peekMin() const;
-  const TYPE& peekElement(int index) const;
-  TYPE extractMin();
-  void print(std::ostream& out) const;
-private:
-  // Private Methods
-  bool verifyHeap() const;
-  bool verifyHeap(HeapIndex index) const;
-  void heapify();
-
-  // Private copy constructor and assignment operator
-  PrioHeap(const PrioHeap& obj);
-  PrioHeap<TYPE>& operator=(const PrioHeap& obj);
-
-  // Data Members (m_ prefix)
-  std::vector<TYPE> m_heap;
-  HeapIndex m_current_size;
-};
-
-// Output operator declaration
-template <class TYPE>
-std::ostream& operator<<(std::ostream& out, const PrioHeap<TYPE>& obj);
-
-// ******************* Helper Functions *******************
-inline
-HeapIndex get_parent(HeapIndex i)
-{
-  //  return (i/2);
-  return (i>>1);
-}
-
-inline
-HeapIndex get_right(HeapIndex i)
-{
-  //  return (2*i) + 1;
-  return (i<<1) | 1;
-}
-
-inline
-HeapIndex get_left(HeapIndex i)
-{
-  //  return (2*i);
-  return (i<<1);
-}
-
-template <class TYPE>
-void prio_heap_swap(TYPE& n1, TYPE& n2)
-{
-  TYPE temp = n1;
-  n1 = n2;
-  n2 = temp;
-}
-
-// ******************* Definitions *******************
-
-template <class TYPE>
-void PrioHeap<TYPE>::insert(const TYPE& key)
-{
-  int i;
-  // grow the vector size
-  m_current_size++;
-  m_heap.resize(m_current_size+1);
-
-  if(m_current_size == 1){      // HACK: need to initialize index 0 to avoid purify UMCs
-    m_heap[0] = key;
-  }
-
-  i = m_current_size;
-  while ((i > 1) && (node_less_then_eq(key, m_heap[get_parent(i)]))) {
-    m_heap[i] = m_heap[get_parent(i)];
-    i = get_parent(i);
-  }
-  m_heap[i] = key;
-  //  assert(verifyHeap());
-}
-
-template <class TYPE>
-const TYPE& PrioHeap<TYPE>::peekMin() const
-{
-  assert(size() > 0);
-  return m_heap[1]; // 1, not 0, is the first element
-}
-
-template <class TYPE>
-const TYPE& PrioHeap<TYPE>::peekElement(int index) const
-{
-  assert(size() > 0);
-  return m_heap[index];
-}
-
-template <class TYPE>
-TYPE PrioHeap<TYPE>::extractMin()
-{
-  //  TYPE temp;
-  assert(size() > 0);
-  TYPE temp = m_heap[1]; // 1, not 0, is the first element
-  m_heap[1] = m_heap[m_current_size];
-  m_current_size--;
-  heapify();
-  return temp;
-}
-
-template <class TYPE>
-bool PrioHeap<TYPE>::verifyHeap() const
-{
-  return verifyHeap(1);
-}
-
-template <class TYPE>
-bool PrioHeap<TYPE>::verifyHeap(HeapIndex index) const
-{
-  // Recursively verify that each node is <= its parent
-  if(index > m_current_size) {
-    return true;
-  } else if (index == 1) {
-    return
-      verifyHeap(get_right(index)) &&
-      verifyHeap(get_left(index));
-  } else if (node_less_then_eq(m_heap[get_parent(index)], m_heap[index])) {
-    return
-      verifyHeap(get_right(index)) &&
-      verifyHeap(get_left(index));
-  } else {
-    // Heap property violation
-    return false;
-  }
-}
-
-template <class TYPE>
-void PrioHeap<TYPE>::heapify()
-{
-  HeapIndex current_node = 1;
-  HeapIndex left, right, smallest;
-  //  HeapIndex size = m_current_size;
-
-  while(true) {
-    left = get_left(current_node);
-    right = get_right(current_node);
-
-    // Find the smallest of the current node and children
-    if (left <= m_current_size && node_less_then_eq(m_heap[left], m_heap[current_node])) {
-      smallest = left;
-    } else {
-      smallest = current_node;
-    }
-
-    if (right <= m_current_size && node_less_then_eq(m_heap[right], m_heap[smallest])) {
-      smallest = right;
-    }
-
-    // Check to see if we are done
-    if (smallest == current_node) {
-      // We are done
-      break;
-    } else {
-      // Not done, heapify on the smallest child
-      prio_heap_swap(m_heap[current_node], m_heap[smallest]);
-      current_node = smallest;
-    }
-  }
-  //  assert(verifyHeap());
-}
-
-template <class TYPE>
-void PrioHeap<TYPE>::print(std::ostream& out) const
-{
-  std::vector<TYPE> copyHeap(m_heap);
-
-  // sort copyHeap (inefficient, but will not be done often)
-
-  for(HeapIndex i=0;i<m_current_size; i++){
-    for(HeapIndex j=0; j< m_current_size; j++){
-      if(copyHeap[i].m_time < copyHeap[j].m_time){
-        prio_heap_swap(copyHeap[i], copyHeap[j]);
-      }
-    }
-  }
-
-  out << "[PrioHeap: ";
-
-  for(HeapIndex i=1; i<= m_current_size; i++){
-    out << copyHeap[i];
-
-    if(i != m_current_size-1){
-      out << ",";
-    }
-    out << " ";
-  }
-  out << "]";
-}
-
-// Output operator definition
-template <class TYPE>
-std::ostream& operator<<(std::ostream& out, const PrioHeap<TYPE>& obj)
-{
-  obj.print(out);
-  out << std::flush;
-  return out;
-}
-
-#endif //PRIOHEAP_H
index 26d1873054358c72c41220c1daea95ac2250f7d2..9cd1dd47b4dbaf7b2bc79afd60260c83254536c1 100644 (file)
  */
 
 #include "base/cprintf.hh"
+#include "base/stl_helpers.hh"
 #include "mem/ruby/buffers/MessageBuffer.hh"
 #include "mem/ruby/system/System.hh"
 
 using namespace std;
+using m5::stl_helpers::operator<<;
 
 MessageBuffer::MessageBuffer(const string &name)
 {
@@ -111,7 +113,7 @@ MessageBuffer::getMsgPtrCopy() const
 {
     assert(isReady());
 
-    return m_prio_heap.peekMin().m_msgptr->clone();
+    return m_prio_heap.front().m_msgptr->clone();
 }
 
 const Message*
@@ -124,7 +126,7 @@ MessageBuffer::peekAtHeadOfQueue() const
                        m_name, g_eventQueue_ptr->getTime()));
     assert(isReady());
 
-    const Message* msg_ptr = m_prio_heap.peekMin().m_msgptr.get();
+    const Message* msg_ptr = m_prio_heap.front().m_msgptr.get();
     assert(msg_ptr);
 
     DEBUG_EXPR(QUEUE_COMP, MedPrio, *msg_ptr);
@@ -223,7 +225,9 @@ MessageBuffer::enqueue(MsgPtr message, Time delta)
 
     // Insert the message into the priority heap
     MessageBufferNode thisNode(arrival_time, m_msg_counter, message);
-    m_prio_heap.insert(thisNode);
+    m_prio_heap.push_back(thisNode);
+    push_heap(m_prio_heap.begin(), m_prio_heap.end(),
+        greater<MessageBufferNode>());
 
     DEBUG_NEWLINE(QUEUE_COMP, HighPrio);
     DEBUG_MSG(QUEUE_COMP, HighPrio,
@@ -260,7 +264,7 @@ void
 MessageBuffer::dequeue(MsgPtr& message)
 {
     DEBUG_MSG(QUEUE_COMP, MedPrio, "dequeue from " + m_name);
-    message = m_prio_heap.peekMin().m_msgptr;
+    message = m_prio_heap.front().m_msgptr;
 
     pop();
     DEBUG_EXPR(QUEUE_COMP, MedPrio, message);
@@ -272,7 +276,7 @@ MessageBuffer::dequeue_getDelayCycles()
     int delay_cycles = -1;  // null value
 
     // get MsgPtr of the message about to be dequeued
-    MsgPtr message = m_prio_heap.peekMin().m_msgptr;
+    MsgPtr message = m_prio_heap.front().m_msgptr;
 
     // get the delay cycles
     delay_cycles = setAndReturnDelayCycles(message);
@@ -288,7 +292,10 @@ MessageBuffer::pop()
 {
     DEBUG_MSG(QUEUE_COMP, MedPrio, "pop from " + m_name);
     assert(isReady());
-    m_prio_heap.extractMin();
+    pop_heap(m_prio_heap.begin(), m_prio_heap.end(),
+        greater<MessageBufferNode>());
+    m_prio_heap.pop_back();
+
     // record previous size and time so the current buffer size isn't
     // adjusted until next cycle
     if (m_time_last_time_pop < g_eventQueue_ptr->getTime()) {
@@ -301,11 +308,7 @@ MessageBuffer::pop()
 void
 MessageBuffer::clear()
 {
-    while(m_prio_heap.size() > 0){
-        m_prio_heap.extractMin();
-    }
-
-    ASSERT(m_prio_heap.size() == 0);
+    m_prio_heap.clear();
 
     m_msg_counter = 0;
     m_size = 0;
@@ -320,9 +323,13 @@ MessageBuffer::recycle()
 {
     DEBUG_MSG(QUEUE_COMP, MedPrio, "recycling " + m_name);
     assert(isReady());
-    MessageBufferNode node = m_prio_heap.extractMin();
+    MessageBufferNode node = m_prio_heap.front();
+    pop_heap(m_prio_heap.begin(), m_prio_heap.end(),
+        greater<MessageBufferNode>());
     node.m_time = g_eventQueue_ptr->getTime() + m_recycle_latency;
-    m_prio_heap.insert(node);
+    m_prio_heap.back() = node;
+    push_heap(m_prio_heap.begin(), m_prio_heap.end(),
+        greater<MessageBufferNode>());
     g_eventQueue_ptr->scheduleEventAbsolute(m_consumer_ptr,
         g_eventQueue_ptr->getTime() + m_recycle_latency);
 }
@@ -353,7 +360,10 @@ MessageBuffer::print(ostream& out) const
     if (m_consumer_ptr != NULL) {
         out << " consumer-yes ";
     }
-    out << m_prio_heap << "] " << m_name << endl;
+
+    vector<MessageBufferNode> copy(m_prio_heap);
+    sort_heap(copy.begin(), copy.end(), greater<MessageBufferNode>());
+    out << copy << "] " << m_name << endl;
 }
 
 void
index 12799c871c0571fbe8b0c002ddcab944553e314a..9315eaec04bb74256890af1af5c7681006891c15 100644 (file)
 #ifndef __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__
 #define __MEM_RUBY_BUFFERS_MESSAGEBUFFER_HH__
 
+#include <algorithm>
+#include <functional>
 #include <iostream>
+#include <vector>
 #include <string>
 
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/ruby/buffers/MessageBufferNode.hh"
 #include "mem/ruby/common/Consumer.hh"
 #include "mem/ruby/common/Global.hh"
@@ -61,13 +63,16 @@ class MessageBuffer
     isReady() const
     {
         return ((m_prio_heap.size() > 0) &&
-                (m_prio_heap.peekMin().m_time <= g_eventQueue_ptr->getTime()));
+                (m_prio_heap.front().m_time <= g_eventQueue_ptr->getTime()));
     }
 
     void
     delayHead()
     {
-        MessageBufferNode node = m_prio_heap.extractMin();
+        MessageBufferNode node = m_prio_heap.front();
+        std::pop_heap(m_prio_heap.begin(), m_prio_heap.end(),
+                      std::greater<MessageBufferNode>());
+        m_prio_heap.pop_back();
         enqueue(node.m_msgptr, 1);
     }
 
@@ -93,13 +98,13 @@ class MessageBuffer
     peekMsgPtr() const
     {
         assert(isReady());
-        return m_prio_heap.peekMin().m_msgptr;
+        return m_prio_heap.front().m_msgptr;
     }
 
     const MsgPtr&
     peekMsgPtrEvenIfNotReady() const
     {
-        return m_prio_heap.peekMin().m_msgptr;
+        return m_prio_heap.front().m_msgptr;
     }
 
     void enqueue(MsgPtr message) { enqueue(message, 1); }
@@ -144,7 +149,7 @@ class MessageBuffer
 
     // Data Members (m_ prefix)
     Consumer* m_consumer_ptr;  // Consumer to signal a wakeup(), can be NULL
-    PrioHeap<MessageBufferNode> m_prio_heap;
+    std::vector<MessageBufferNode> m_prio_heap;
     std::string m_name;
 
     int m_max_size;
index 9ead9b9aab9b6ecc9ac0b4229913454f49cfa3f7..078da47c469fde1425e50250645436042dba75d5 100644 (file)
@@ -59,13 +59,13 @@ class MessageBufferNode
 };
 
 inline bool
-node_less_then_eq(const MessageBufferNode& n1, const MessageBufferNode& n2)
+operator>(const MessageBufferNode& n1, const MessageBufferNode& n2)
 {
     if (n1.m_time == n2.m_time) {
         assert(n1.m_msg_counter != n2.m_msg_counter);
-        return (n1.m_msg_counter <= n2.m_msg_counter);
+        return n1.m_msg_counter > n2.m_msg_counter;
     } else {
-        return (n1.m_time <= n2.m_time);
+        return n1.m_time > n2.m_time;
     }
 }
 
index 4a0fb9ceb80fcb2eeb83f1c489c6d2d73325304b..6fa8b0ac39a298d31ecd6406b3411b38c07b7143 100644 (file)
@@ -63,7 +63,6 @@
 #include "sim/eventq.hh"
 
 class Consumer;
-template <class TYPE> class PrioHeap;
 class RubyEventQueueNode;
 
 class RubyEventQueue : public EventManager
index 29699562d73c08996ecf0af040d6fe2cd0f38113..39fdd3c6f1be3c1720d50e971889632612b2e739 100644 (file)
@@ -37,7 +37,6 @@
 #include "mem/ruby/network/garnet/NetworkHeader.hh"
 #include "mem/ruby/common/Consumer.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/flitBuffer_d.hh"
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/ruby/network/orion/power_bus.hh"
 
 class GarnetNetwork_d;
index 38510c7581b9686eb6f8e4dba6430d0979f543aa..5387604d40e46ede2d60a73986e5c6d91e52792d 100644 (file)
@@ -49,7 +49,7 @@ bool flitBuffer_d::isReady()
 {
         if(m_buffer.size() != 0 )
         {
-                flit_d *t_flit = m_buffer.peekMin();
+                flit_d *t_flit = peekTopFlit();
                 if(t_flit->get_time() <= g_eventQueue_ptr->getTime())
                         return true;
         }
@@ -60,7 +60,7 @@ bool flitBuffer_d::isReadyForNext()
 {
         if(m_buffer.size() != 0 )
         {
-                flit_d *t_flit = m_buffer.peekMin();
+                flit_d *t_flit = peekTopFlit();
                 if(t_flit->get_time() <= (g_eventQueue_ptr->getTime() + 1))
                         return true;
         }
index 976fa4053e942c90fb30e1822a43a3c2a7235281..8aa869f82b69fd0852ce182a0a5f98e834771d92 100644 (file)
 #ifndef FLIT_BUFFER_D_H
 #define FLIT_BUFFER_D_H
 
+#include <algorithm>
 #include <iostream>
+#include <vector>
 
 #include "mem/ruby/network/garnet/NetworkHeader.hh"
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/flit_d.hh"
 
 class flitBuffer_d {
@@ -51,19 +52,23 @@ public:
 
         inline flit_d* getTopFlit()
         {
-                return m_buffer.extractMin();
+            flit_d *f = m_buffer.front();
+            std::pop_heap(m_buffer.begin(), m_buffer.end(), flit_d::greater);
+            m_buffer.pop_back();
+            return f;
         }
         inline flit_d* peekTopFlit()
         {
-                return m_buffer.peekMin();
+            return m_buffer.front();
         }
         inline void insert(flit_d *flt)
         {
-                m_buffer.insert(flt);
+            m_buffer.push_back(flt);
+            std::push_heap(m_buffer.begin(), m_buffer.end(), flit_d::greater);
         }
         /**********Data Members*********/
 private:
-        PrioHeap <flit_d *> m_buffer;
+        std::vector<flit_d *> m_buffer;
         int size, max_size;
 };
 
index 39bbe011d543ef2ff1f8d579f60a76b2c481165e..ec2774a942353e34a6fefef2f6ae60d4f637b111 100644 (file)
@@ -115,6 +115,16 @@ public:
                 return src_delay;
         }
 
+        static bool
+        greater(flit_d* n1, flit_d* n2)
+        {
+            if (n1->get_time() == n2->get_time()) {
+                //ASSERT(n1->flit_id != n2->flit_id);
+                return (n1->get_id() > n2->get_id());
+            } else {
+                return (n1->get_time() > n2->get_time());
+            }
+        }
 
 private:
         /************Data Members*************/
@@ -132,19 +142,6 @@ private:
 
 };
 
-inline extern bool node_less_then_eq(flit_d* n1, flit_d* n2);
-
-inline extern
-bool node_less_then_eq(flit_d* n1, flit_d* n2)
-{
-  if (n1->get_time() == n2->get_time()) {
-//    ASSERT(n1->flit_id != n2->flit_id);
-    return (n1->get_id() <= n2->get_id());
-  } else {
-    return (n1->get_time() <= n2->get_time());
-  }
-}
-
 inline std::ostream&
 operator<<(std::ostream& out, const flit_d& obj)
 {
index c23d55b484eb665c606f209b6fec78e59565e5d4..9f1311dcebd6ac9eb79d7011def7b27a4f914605 100644 (file)
@@ -37,7 +37,6 @@
 #include "mem/ruby/network/garnet/NetworkHeader.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh"
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/ruby/common/NetDest.hh"
 
 class GarnetNetwork;
index b6ebb601f7928671f0dbde9db209235065afdd15..16b19204aebe3973f9e172229989cb41661caf8d 100644 (file)
@@ -37,7 +37,6 @@
 #include "mem/ruby/network/garnet/NetworkHeader.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/FlexibleConsumer.hh"
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
 #include "mem/ruby/common/NetDest.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh"
index 1cc8806e9c28c1d372c0d8653a1620b7a004722b..5aa01c5e7ab7740a582c82825dc254880722e15a 100644 (file)
@@ -52,6 +52,16 @@ public:
         flit_type get_type();
         void print(std::ostream& out) const;
 
+        static bool
+        greater(flit* n1, flit* n2)
+        {
+            if (n1->get_time() == n2->get_time())
+                //ASSERT(n1->flit_id != n2->flit_id);
+                return (n1->get_id() > n2->get_id());
+            else
+                return (n1->get_time() > n2->get_time());
+        }
+
 private:
 /************Data Members*************/
         int m_id;
@@ -64,19 +74,6 @@ private:
 
 };
 
-inline extern bool node_less_then_eq(flit* n1, flit* n2);
-
-inline extern
-bool node_less_then_eq(flit* n1, flit* n2)
-{
-  if (n1->get_time() == n2->get_time()) {
-//    ASSERT(n1->flit_id != n2->flit_id);
-    return (n1->get_id() <= n2->get_id());
-  } else {
-    return (n1->get_time() <= n2->get_time());
-  }
-}
-
 inline std::ostream&
 operator<<(std::ostream& out, const flit& obj)
 {
index 7f41d6f8c6a32030e55b497b40e935faedab2973..82eb08902cb6bc8e26271d0e27c525cf989ba51b 100644 (file)
  * Authors: Niket Agarwal
  */
 
+#include <algorithm>
+
 #include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh"
 
+using namespace std;
+
 flitBuffer::flitBuffer()
 {
         max_size = INFINITE_;
@@ -49,7 +53,7 @@ bool flitBuffer::isReady()
 {
         if(m_buffer.size() != 0 )
         {
-                flit *t_flit = m_buffer.peekMin();
+                flit *t_flit = m_buffer.front();
                 if(t_flit->get_time() <= g_eventQueue_ptr->getTime())
                         return true;
         }
@@ -60,7 +64,7 @@ bool flitBuffer::isReadyForNext()
 {
         if(m_buffer.size() != 0 )
         {
-                flit *t_flit = m_buffer.peekMin();
+                flit *t_flit = m_buffer.front();
                 if(t_flit->get_time() <= (g_eventQueue_ptr->getTime() + 1))
                         return true;
         }
@@ -79,17 +83,21 @@ void flitBuffer::setMaxSize(int maximum)
 
 flit* flitBuffer:: getTopFlit()
 {
-        return m_buffer.extractMin();
+        flit *f = m_buffer.front();
+        pop_heap(m_buffer.begin(), m_buffer.end(), flit::greater);
+        m_buffer.pop_back();
+        return f;
 }
 
 flit* flitBuffer::peekTopFlit()
 {
-        return m_buffer.peekMin();
+        return m_buffer.front();
 }
 
 void flitBuffer::insert(flit *flt)
 {
-        m_buffer.insert(flt);
+        m_buffer.push_back(flt);
+        push_heap(m_buffer.begin(), m_buffer.end(), flit::greater);
 }
 
 void flitBuffer::print(std::ostream& out) const
index 646cd99c7c59cefab844ffb182ea6e47f7e71b13..a5ec2559007d3d6cd04b43f753182e856344a671 100644 (file)
@@ -32,9 +32,9 @@
 #define FLIT_BUFFER_H
 
 #include <iostream>
+#include <vector>
 
 #include "mem/ruby/network/garnet/NetworkHeader.hh"
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/flit.hh"
 
 class flitBuffer {
@@ -54,7 +54,7 @@ public:
 
 /**********Data Members*********/
 private:
-        PrioHeap <flit *> m_buffer;
+        std::vector<flit *> m_buffer;
         int size, max_size;
 };
 
index a707cd4df2d72df09da2dd439752b2788e4c48c4..b950f2be2f05660b833318f5a319b0532e80b9a6 100644 (file)
@@ -60,6 +60,13 @@ class AccessTraceForAddress
 
     void print(std::ostream& out) const;
 
+    static inline bool
+    less_equal(const AccessTraceForAddress* n1,
+        const AccessTraceForAddress* n2)
+    {
+        return n1->getTotal() <= n2->getTotal();
+    }
+
   private:
     Address m_addr;
     uint64 m_loads;
@@ -72,13 +79,6 @@ class AccessTraceForAddress
     Histogram* m_histogram_ptr;
 };
 
-inline bool
-node_less_then_eq(const AccessTraceForAddress* n1,
-                  const AccessTraceForAddress* n2)
-{
-    return n1->getTotal() > n2->getTotal();
-}
-
 inline std::ostream&
 operator<<(std::ostream& out, const AccessTraceForAddress& obj)
 {
index 4274569ad9211b5e683bdd3328d736b3294e79b6..5c1b7352c3ae36985f020aebd7f1c18148ee44f0 100644 (file)
@@ -29,7 +29,6 @@
 #include <vector>
 
 #include "base/stl_helpers.hh"
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/protocol/CacheMsg.hh"
 #include "mem/ruby/profiler/AddressProfiler.hh"
 #include "mem/ruby/profiler/Profiler.hh"
@@ -70,15 +69,16 @@ printSorted(ostream& out, int num_of_sequencers, const AddressMap &record_map,
     const int records_printed = 100;
 
     uint64 misses = 0;
-    PrioHeap<const AccessTraceForAddress*> heap;
+    std::vector<const AccessTraceForAddress *> sorted;
 
     AddressMap::const_iterator i = record_map.begin();
     AddressMap::const_iterator end = record_map.end();
     for (; i != end; ++i) {
         const AccessTraceForAddress* record = &i->second;
         misses += record->getTotal();
-        heap.insert(record);
+        sorted.push_back(record);
     }
+    sort(sorted.begin(), sorted.end(), AccessTraceForAddress::less_equal);
 
     out << "Total_entries_" << description << ": " << record_map.size()
         << endl;
@@ -106,8 +106,9 @@ printSorted(ostream& out, int num_of_sequencers, const AddressMap &record_map,
     }
 
     int counter = 0;
-    while (heap.size() > 0 && counter < records_printed) {
-        const AccessTraceForAddress* record = heap.extractMin();
+    int max = sorted.size();
+    while (counter < max && counter < records_printed) {
+        const AccessTraceForAddress* record = sorted[counter];
         double percent = 100.0 * (record->getTotal() / double(misses));
         out << description << " | " << percent << " % " << *record << endl;
         all_records.add(record->getTotal());
@@ -117,8 +118,8 @@ printSorted(ostream& out, int num_of_sequencers, const AddressMap &record_map,
         m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
     }
 
-    while (heap.size() > 0) {
-        const AccessTraceForAddress* record = heap.extractMin();
+    while (counter < max) {
+        const AccessTraceForAddress* record = sorted[counter];
         all_records.add(record->getTotal());
         remaining_records.add(record->getTotal());
         all_records_log.add(record->getTotal());
index 8ba64add940dcaa1b259a027062e3083070870dd..006617190ce096d18a5492b0b5042ca25be39d43 100644 (file)
@@ -26,7 +26,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/ruby/profiler/CacheProfiler.hh"
 #include "mem/ruby/profiler/Profiler.hh"
 #include "mem/ruby/system/System.hh"
index 33d490a85cc7d3adbc5ccc0b839306542b56a23a..2b844ef9d8c45e0e60e3ff749b0ed969b901a517 100644 (file)
@@ -50,7 +50,6 @@
 
 #include "base/stl_helpers.hh"
 #include "base/str.hh"
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/protocol/CacheMsg.hh"
 #include "mem/protocol/MachineType.hh"
 #include "mem/protocol/Protocol.hh"
index 32db211b60e9681ba1ca2c29549ef4b9e6c23811..1d08eef12a160c230d399ed4db065a15fd22a200 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <algorithm>
+
 #include "gzstream.hh"
 
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/ruby/eventqueue/RubyEventQueue.hh"
 #include "mem/ruby/recorder/CacheRecorder.hh"
-#include "mem/ruby/recorder/TraceRecord.hh"
 
 using namespace std;
 
-CacheRecorder::CacheRecorder()
-{
-    m_records_ptr = new PrioHeap<TraceRecord>;
-}
-
-CacheRecorder::~CacheRecorder()
-{
-    delete m_records_ptr;
-}
-
 void
 CacheRecorder::addRecord(Sequencer* sequencer, const Address& data_addr,
     const Address& pc_addr, RubyRequestType type, Time time)
 {
-    m_records_ptr->
-        insert(TraceRecord(sequencer, data_addr, pc_addr, type, time));
+    TraceRecord rec(sequencer, data_addr, pc_addr, type, time);
+    m_records.push_back(rec);
 }
 
 int
@@ -62,13 +52,15 @@ CacheRecorder::dumpRecords(string filename)
         return 0;
     }
 
-    int counter = 0;
-    while (m_records_ptr->size() != 0) {
-        TraceRecord record = m_records_ptr->extractMin();
-        record.output(out);
-        counter++;
-    }
-    return counter;
+    std::sort(m_records.begin(), m_records.end(), greater<TraceRecord>());
+
+    int size = m_records.size();
+    for (int i = 0; i < size; ++i)
+        m_records[i].output(out);
+
+    m_records.clear();
+
+    return size;
 }
 
 void
index 18c246c9fa673d22fe6dc34e1f6b476f0b7bd23c..14066c387326ff3c5c92d0dd468371a0ad60f871 100644 (file)
 
 #include <iostream>
 #include <string>
+#include <vector>
 
 #include "mem/protocol/CacheRequestType.hh"
 #include "mem/ruby/common/Global.hh"
 #include "mem/ruby/libruby_internal.hh"
 #include "mem/ruby/system/NodeID.hh"
+#include "mem/ruby/recorder/TraceRecord.hh"
 
-template <class TYPE> class PrioHeap;
 class Address;
 class TraceRecord;
 class Sequencer;
@@ -50,9 +51,6 @@ class Sequencer;
 class CacheRecorder
 {
   public:
-    CacheRecorder();
-    ~CacheRecorder();
-
     void addRecord(Sequencer* sequencer, const Address& data_addr,
         const Address& pc_addr, RubyRequestType type, Time time);
     int dumpRecords(std::string filename);
@@ -64,7 +62,7 @@ class CacheRecorder
     CacheRecorder(const CacheRecorder& obj);
     CacheRecorder& operator=(const CacheRecorder& obj);
 
-    PrioHeap<TraceRecord>* m_records_ptr;
+    std::vector<TraceRecord> m_records;
 };
 
 inline std::ostream&
index 98e78b20e7c626750189e45a4cdaded0d7a07fed..ed066debbef849eb12f0c501adcaf2ede95ca022 100644 (file)
@@ -60,12 +60,6 @@ class TraceRecord
     TraceRecord(const TraceRecord& obj);
     TraceRecord& operator=(const TraceRecord& obj);
 
-    bool
-    node_less_then_eq(const TraceRecord& rec) const
-    {
-        return this->m_time <= rec.m_time;
-    }
-
     void issueRequest() const;
 
     void print(std::ostream& out) const;
@@ -73,6 +67,8 @@ class TraceRecord
     bool input(std::istream& in);
 
   private:
+    friend bool operator>(const TraceRecord& n1, const TraceRecord& n2);
+
     Sequencer* m_sequencer_ptr;
     Time m_time;
     Address m_data_address;
@@ -81,9 +77,9 @@ class TraceRecord
 };
 
 inline bool
-node_less_then_eq(const TraceRecord& n1, const TraceRecord& n2)
+operator>(const TraceRecord& n1, const TraceRecord& n2)
 {
-    return n1.node_less_then_eq(n2);
+    return n1.m_time > n2.m_time;
 }
 
 inline std::ostream&
index 23dafdb6cb39dc56879537f78f4b44954fefb1cc..bff59a83287b6976f14bf15299972bae471479b3 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 #include "base/cprintf.hh"
-#include "mem/gems_common/PrioHeap.hh"
 #include "mem/ruby/eventqueue/RubyEventQueue.hh"
 #include "mem/ruby/recorder/TraceRecord.hh"
 #include "mem/ruby/recorder/Tracer.hh"
index d468b4920e40576f9c9cf3e4f6968f8782fc0309..4b81d6121ea4bf0b0e6d054364d9d34c58f8d0da 100644 (file)
@@ -46,7 +46,6 @@
 #include "params/RubyTracer.hh"
 #include "sim/sim_object.hh"
 
-template <class TYPE> class PrioHeap;
 class Address;
 class TraceRecord;
 class Sequencer;