From a4f727f68df3f904f94ecc6c3a2a548e6858cb7e Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Sun, 3 Jun 2007 20:09:56 +0200 Subject: [PATCH] a bunch of optimizations --- src/common/packet-history.cc | 469 +++++++++++++++++++++-------------- src/common/packet-history.h | 82 +++++- utils/bench-packets.cc | 15 +- 3 files changed, 364 insertions(+), 202 deletions(-) diff --git a/src/common/packet-history.cc b/src/common/packet-history.cc index 2a5843ff5..b5b70af03 100644 --- a/src/common/packet-history.cc +++ b/src/common/packet-history.cc @@ -22,10 +22,15 @@ #include #include "ns3/assert.h" #include "ns3/fatal-error.h" +#include "ns3/debug.h" #include "packet-history.h" #include "chunk.h" #include "buffer.h" +NS_DEBUG_COMPONENT_DEFINE ("PacketHistory"); + +#define noUSE_ULEB 1 + namespace { class ItemList @@ -278,6 +283,44 @@ namespace ns3 { bool PacketHistory::m_enable = false; uint32_t PacketHistory::m_maxSize = 0; PacketHistory::DataFreeList PacketHistory::m_freeList; +uint32_t g_nAllocs = 0; +uint32_t g_nDeAllocs = 0; +uint32_t g_nRecycle = 0; +uint32_t g_nCreate = 0; + uint32_t g_one = 0; + uint32_t g_two = 0; + uint32_t g_three = 0; + uint32_t g_four = 0; + uint32_t g_five = 0; + +void +PacketHistory::PrintStats (void) +{ + std::cout << "allocs="<m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + uint8_t *start = &m_data->m_data[m_end]; + uint8_t *current = start; + if (TryToAppendSmallValue (type, ¤t) && + TryToAppendSmallValue (data0, ¤t) && + TryToAppendValue (data1, ¤t)) + { + uintptr_t written = current - start; + m_end += written; + m_data->m_dirtyEnd = m_end; + m_n++; + g_one++; + return; + } + } + + g_two++; + uint32_t n = GetUleb128Size (type); + n += GetUleb128Size (data0); + n += GetUleb128Size (data1); + Reserve (n); + AppendValue (type); + AppendValue (data0); + AppendValue (data1); + m_n++; + +#else + restart: + if (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + uint32_t *start = (uint32_t *)&m_data->m_data[m_end]; + uint32_t *end = (uint32_t *)&m_data->m_data[m_data->m_size]; + if (start + 2 < end) + { + start[0] = type; + start[1] = data0; + start[2] = data1; + m_end += 12; + m_data->m_dirtyEnd = m_end; + m_n++; + g_one++; + return; + } + } + g_two++; + Reserve (12); + goto restart; +#endif +} + +void +PacketHistory::AppendOneCommand (uint32_t type, uint32_t data) +{ + NS_ASSERT (m_data != 0); +#ifdef USE_ULEB + if (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + uint8_t *start = &m_data->m_data[m_end]; + uint8_t *current = start; + if (TryToAppendSmallValue (type, ¤t) && + TryToAppendSmallValue (data, ¤t)) + { + uintptr_t written = current - start; + m_end += written; + m_data->m_dirtyEnd = m_end; + m_n++; + g_one++; + return; + } + } + + g_two++; + uint32_t n = GetUleb128Size (data); + n += GetUleb128Size (type); + Reserve (n); + AppendValue (type); + AppendValue (data); + m_n++; +#else + restart: + if (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end) + { + uint32_t *start = (uint32_t *)&m_data->m_data[m_end]; + uint32_t *end = (uint32_t *)&m_data->m_data[m_data->m_size]; + if (start + 1 < end) + { + start[0] = type; + start[1] = data; + m_end += 8; + m_data->m_dirtyEnd = m_end; + m_n++; + g_one++; + return; + } + } + g_two++; + Reserve (8); + goto restart; +#endif +} +void +PacketHistory::ReserveCopy (uint32_t size) +{ + struct CommandData *newData = PacketHistory::Create (m_end + size); + memcpy (newData->m_data, m_data->m_data, m_end); + newData->m_dirtyEnd = m_end; + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + m_data = newData; +} +void +PacketHistory::Reserve (uint32_t size) +{ + NS_ASSERT (m_data != 0); + if (m_data->m_size >= m_end + size && + (m_data->m_count == 1 || + m_data->m_dirtyEnd == m_end)) + { + /* enough room, not dirty. */ + g_four++; + } + else + { + /* (enough room and dirty) or (not enough room) */ + ReserveCopy (size); + g_five++; + } } uint32_t @@ -666,7 +750,6 @@ PacketHistory::AddAtEnd (PacketHistory const&o) { if (m_enable) { - m_aggregated = true; uint32_t n = GetUleb128Size (PacketHistory::ADD_AT_END); n += GetUleb128Size (o.m_end); n += GetUleb128Size (o.m_n); diff --git a/src/common/packet-history.h b/src/common/packet-history.h index 6d2fc6834..99ebf794b 100644 --- a/src/common/packet-history.h +++ b/src/common/packet-history.h @@ -39,10 +39,10 @@ class PacketHistory { public: static void Enable (void); - PacketHistory (uint32_t uid, uint32_t size); - PacketHistory (PacketHistory const &o); - PacketHistory &operator = (PacketHistory const& o); - ~PacketHistory (); + inline PacketHistory (uint32_t uid, uint32_t size); + inline PacketHistory (PacketHistory const &o); + inline PacketHistory &operator = (PacketHistory const& o); + inline ~PacketHistory (); template void AddHeader (T const &header, uint32_t size); @@ -63,6 +63,8 @@ public: void PrintDefault (std::ostream &os, Buffer buffer) const; void Print (std::ostream &os, Buffer buffer, PacketPrinter const &printer) const; + static void PrintStats (void); + private: enum CommandType { INIT = 0, @@ -88,9 +90,8 @@ private: PacketHistory (); void Reserve (uint32_t n); - void Construct (uint32_t uid, uint32_t size); + inline void Construct (uint32_t uid, uint32_t size); uint32_t GetUleb128Size (uint32_t value) const; - uint32_t GetReverseUleb128Size (uint8_t *buffer) const; void AppendValue (uint32_t value); uint32_t ReadForwardValue (uint8_t **pBuffer) const; uint32_t ReadValue (uint8_t *buffer, uint32_t *n) const; @@ -103,6 +104,8 @@ private: void RemoveTrailer (uint32_t uid, Chunk const & trailer, uint32_t size); void PrintComplex (std::ostream &os, Buffer buffer, const PacketPrinter &printer) const; void BuildItemList (ItemList *list, uint8_t **buffer, uint32_t size, uint32_t n) const; + inline bool TryToAppendValue (uint32_t value, uint8_t **buffer); + inline bool TryToAppendSmallValue (uint32_t value, uint8_t **buffer); static struct PacketHistory::CommandData *Create (uint32_t size); static void Recycle (struct CommandData *data); @@ -116,7 +119,6 @@ private: struct CommandData *m_data; uint32_t m_end; uint32_t m_n; - bool m_aggregated; }; }; // namespace ns3 @@ -149,6 +151,72 @@ PacketHistory::RemoveTrailer (T const &trailer, uint32_t size) RemoveTrailer (PacketPrinter::GetUid (), trailer, size); } + +PacketHistory::PacketHistory (uint32_t uid, uint32_t size) + : m_data (0), + m_end (0), + m_n (0) +{ + Construct (uid, size); +} +void +PacketHistory::Construct (uint32_t uid, uint32_t size) +{ + if (m_enable) + { + m_data = PacketHistory::Create (0); + AppendOneCommand (PacketHistory::INIT, + size, uid); + } +} +PacketHistory::PacketHistory (PacketHistory const &o) + : m_data (o.m_data), + m_end (o.m_end), + m_n (o.m_n) +{ + if (m_data != 0) + { + m_data->m_count++; + } +} +PacketHistory & +PacketHistory::operator = (PacketHistory const& o) +{ + if (m_data == o.m_data) + { + // self assignment + return *this; + } + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } + m_data = o.m_data; + m_end = o.m_end; + m_n = o.m_n; + if (m_data != 0) + { + m_data->m_count++; + } + return *this; +} +PacketHistory::~PacketHistory () +{ + if (m_data != 0) + { + m_data->m_count--; + if (m_data->m_count == 0) + { + PacketHistory::Recycle (m_data); + } + } +} + + }; // namespace ns3 diff --git a/utils/bench-packets.cc b/utils/bench-packets.cc index 9d44a557f..74daa70fd 100644 --- a/utils/bench-packets.cc +++ b/utils/bench-packets.cc @@ -20,6 +20,7 @@ */ #include "ns3/system-wall-clock-ms.h" #include "ns3/packet.h" +#include "ns3/packet-history.h" #include #include @@ -173,17 +174,27 @@ int main (int argc, char *argv[]) { uint32_t n = 0; while (argc > 0) { - if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) { + if (strncmp ("--n=", argv[0],strlen ("--n=")) == 0) + { char const *nAscii = argv[0] + strlen ("--n="); n = atoi (nAscii); - } + } + if (strncmp ("--enable-history", argv[0], strlen ("--enable-history")) == 0) + { + PacketHistory::Enable (); + } argc--; argv++; } + + runBench (&benchPtrA, n, "a"); + PacketHistory::PrintStats (); runBench (&benchPtrB, n, "b"); + PacketHistory::PrintStats (); runBench (&benchPtrC, n, "c"); + PacketHistory::PrintStats (); return 0; }