[Avida-SVN] r3408 - in development/source: cpu main targets/avida-viewer

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Wed Sep 16 13:20:14 PDT 2009


Author: brysonda
Date: 2009-09-16 16:20:14 -0400 (Wed, 16 Sep 2009)
New Revision: 3408

Modified:
   development/source/cpu/cHardwareBase.cc
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareExperimental.cc
   development/source/cpu/cHeadCPU.cc
   development/source/cpu/cHeadCPU.h
   development/source/main/cAvidaContext.h
   development/source/targets/avida-viewer/cTextViewerDriver.cc
Log:
Implement a few performance enhancements
- Altered organism fault reporting to be disabled by default. Enabled only when  running the viewer.  This saves unnecessary calls to Stringf().
- Changed cHeadCPU::Adjust to have an inline early exit test to save some function call overhead, falling back to fullAdjust when necessary.
- Added cHeadCPU::QuickAdjust for situations where the hardware object can easily inform the head of the memory size.  Saves an otherwise expensive virtual function call.

These tweaks yield about a 10% performance improvement for landscaping (and other analyze commands), as well as a 4% improvement in run performance.

Modified: development/source/cpu/cHardwareBase.cc
===================================================================
--- development/source/cpu/cHardwareBase.cc	2009-09-16 18:41:38 UTC (rev 3407)
+++ development/source/cpu/cHardwareBase.cc	2009-09-16 20:20:14 UTC (rev 3408)
@@ -82,6 +82,8 @@
 
 bool cHardwareBase::Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size, bool using_repro)
 {
+#define ORG_FAULT(error) if (ctx.OrgFaultReporting()) m_organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR, error)
+  
   // Make sure the organism is okay with dividing now...
   if (m_organism->Divide_CheckViable() == false) return false; // (divide fails)
   
@@ -92,13 +94,11 @@
   const int max_size = Min(MAX_CREATURE_SIZE, static_cast<int>(genome_size * size_range));
   
   if (child_size < min_size || child_size > max_size) {
-    m_organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-                    cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
+    ORG_FAULT(cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
     return false; // (divide fails)
   }
   if (parent_size < min_size || parent_size > max_size) {
-    m_organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-                    cStringUtil::Stringf("Invalid post-divide length (%d)",parent_size));
+    ORG_FAULT(cStringUtil::Stringf("Invalid post-divide length (%d)",parent_size));
     return false; // (divide fails)
   }
   
@@ -106,14 +106,12 @@
   const int max_genome_size = m_world->GetConfig().MAX_GENOME_SIZE.Get();
   const int min_genome_size = m_world->GetConfig().MIN_GENOME_SIZE.Get();
   if ( (min_genome_size && (child_size < min_genome_size)) || (max_genome_size && (child_size > max_genome_size)) ) {
-    m_organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-                    cStringUtil::Stringf("Invalid absolute offspring length (%d)",child_size));
+    ORG_FAULT(cStringUtil::Stringf("Invalid absolute offspring length (%d)",child_size));
     return false; // (divide fails)
   }
   
   if ( (min_genome_size && (parent_size < min_genome_size)) || (max_genome_size && (parent_size > max_genome_size)) ) {
-    m_organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-                    cStringUtil::Stringf("Invalid absolute post-divide length (%d)",parent_size));
+    ORG_FAULT(cStringUtil::Stringf("Invalid absolute post-divide length (%d)",parent_size));
     return false; // (divide fails)
   }
   
@@ -123,8 +121,7 @@
   const int executed_size = calcExecutedSize(parent_size);
   const int min_exe_lines = static_cast<int>(parent_size * m_world->GetConfig().MIN_EXE_LINES.Get());
   if (executed_size < min_exe_lines) {
-    m_organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-                    cStringUtil::Stringf("Too few executed lines (%d < %d)", executed_size, min_exe_lines));
+    ORG_FAULT(cStringUtil::Stringf("Too few executed lines (%d < %d)", executed_size, min_exe_lines));
     return false; // (divide fails)
   }
   
@@ -136,8 +133,7 @@
     const int min_copied = static_cast<int>(child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
   
     if (copied_size < min_copied) {
-      m_organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-                      cStringUtil::Stringf("Too few copied commands (%d < %d)", copied_size, min_copied));
+      ORG_FAULT(cStringUtil::Stringf("Too few copied commands (%d < %d)", copied_size, min_copied));
       return false; // (divide fails)
     }
   }
@@ -190,6 +186,7 @@
   }
   
   return true; // (divide succeeds!)
+#undef ORG_FAULT
 }
 
 

Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2009-09-16 18:41:38 UTC (rev 3407)
+++ development/source/cpu/cHardwareCPU.cc	2009-09-16 20:20:14 UTC (rev 3408)
@@ -778,7 +778,7 @@
     
     m_advance_ip = true;
     cHeadCPU& ip = m_threads[m_cur_thread].heads[nHardware::HEAD_IP];
-    ip.Adjust();
+    ip.QuickAdjust(m_memory.GetSize());
     
 #if BREAKPOINTS
     if (ip.FlagBreakpoint()) {
@@ -1016,19 +1016,17 @@
   // Call special functions depending on if jump is forwards or backwards.
   int found_pos = 0;
   if( direction < 0 ) {
-    found_pos = FindLabel_Backward(search_label, inst_ptr.GetMemory(),
-                                   inst_ptr.GetPosition() - search_label.GetSize());
+    found_pos = FindLabel_Backward(search_label, m_memory, inst_ptr.GetPosition() - search_label.GetSize());
   }
   
   // Jump forward.
   else if (direction > 0) {
-    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(),
-                                  inst_ptr.GetPosition());
+    found_pos = FindLabel_Forward(search_label, m_memory, inst_ptr.GetPosition());
   }
   
   // Jump forward from the very beginning.
   else {
-    found_pos = FindLabel_Forward(search_label, inst_ptr.GetMemory(), 0);
+    found_pos = FindLabel_Forward(search_label, m_memory, 0);
   }
   
   // Return the last line of the found label, if it was found.
@@ -1292,7 +1290,7 @@
 {
   for (int i = 0; i < m_threads.GetSize(); i++) {
     for (int j = 0; j < NUM_HEADS; j++) {
-      m_threads[i].heads[j].Adjust();
+      m_threads[i].heads[j].QuickAdjust(m_memory.GetSize());
     }
   }
 }
@@ -3190,7 +3188,6 @@
   double stored_energy = m_organism->GetPhenotype().GetStoredEnergy() * m_world->GetConfig().FRAC_ENERGY_RELINQUISH.Get();
   // put stored energy into toBeApplied energy pool of neighbor organisms
   int numOcuppiedNeighbors(0);
-  int orginalFacing = m_organism->GetFacing();
   for(int i = 0; i < m_organism->GetNeighborhoodSize(); i++) {
     if(m_organism->IsNeighborCellOccupied()) {
       // count neighboring organisms
@@ -5673,9 +5670,9 @@
   }
 }
 
-bool cHardwareCPU::Inst_MoveToEvent(cAvidaContext& ctx) {
+bool cHardwareCPU::Inst_MoveToEvent(cAvidaContext& ctx)
+{
   const int reg_used = FindModifiedRegister(REG_BX);
-  int orginalFacing = m_organism->GetFacing();
   
   for(int i = 0; i < m_organism->GetNeighborhoodSize(); i++) {
     if(m_organism->GetNeighborCellContents() > 0) { 
@@ -5691,9 +5688,8 @@
   return true;
 }
 
-bool cHardwareCPU::Inst_IfNeighborEventInUnoccupiedCell(cAvidaContext& ctx) {
-  int orginalFacing = m_organism->GetFacing();
-  
+bool cHardwareCPU::Inst_IfNeighborEventInUnoccupiedCell(cAvidaContext& ctx)
+{
   for(int i = 0; i < m_organism->GetNeighborhoodSize(); i++) {
     if(m_organism->GetNeighborCellContents() > 0 && !m_organism->IsNeighborCellOccupied()) { 
       return true;
@@ -5705,7 +5701,8 @@
   return true;
 }
 
-bool cHardwareCPU::Inst_IfFacingEventCell(cAvidaContext& ctx) {
+bool cHardwareCPU::Inst_IfFacingEventCell(cAvidaContext& ctx)
+{
   if(m_organism->GetNeighborCellContents() > 0) { 
       return true;
   }
@@ -5713,7 +5710,8 @@
   return true;
 }
 
-bool cHardwareCPU::Inst_IfEventInCell(cAvidaContext& ctx) {
+bool cHardwareCPU::Inst_IfEventInCell(cAvidaContext& ctx)
+{
   if(m_organism->GetCellData() > 0) { 
       return true;
   }
@@ -6071,7 +6069,7 @@
   const int dst = REG_BX;
   
   const int head_id = FindModifiedHead(nHardware::HEAD_READ);
-  GetHead(head_id).Adjust();
+  GetHead(head_id).QuickAdjust(m_memory.GetSize());
   
   // Mutations only occur on the read, for the moment.
   int read_inst = 0;
@@ -6084,7 +6082,7 @@
   ReadInst(read_inst);
   
   if (m_slip_read_head && m_organism->TestCopySlip(ctx))
-    GetHead(head_id).Set(ctx.GetRandom().GetInt(GetHead(head_id).GetMemory().GetSize()));
+    GetHead(head_id).Set(ctx.GetRandom().GetInt(m_memory.GetSize()));
 
   GetHead(head_id).Advance();
   return true;
@@ -6096,7 +6094,7 @@
   const int head_id = FindModifiedHead(nHardware::HEAD_WRITE);
   cHeadCPU& active_head = GetHead(head_id);
   
-  active_head.Adjust();
+  active_head.QuickAdjust(m_memory.GetSize());
   
   int value = GetRegister(src);
   if (value < 0 || value >= m_inst_set->GetSize()) value = 0;
@@ -6108,7 +6106,7 @@
   if (m_organism->TestCopyDel(ctx)) active_head.RemoveInst();
   if (m_organism->TestCopyUniform(ctx)) doUniformCopyMutation(ctx, active_head);
   if (!m_slip_read_head && m_organism->TestCopySlip(ctx)) 
-    doSlipMutation(ctx, active_head.GetMemory(), active_head.GetPosition());
+    doSlipMutation(ctx, m_memory, active_head.GetPosition());
 
   // Advance the head after write...
   active_head.Advance();
@@ -6122,8 +6120,8 @@
   cHeadCPU& read_head = GetHead(nHardware::HEAD_READ);
   cHeadCPU& write_head = GetHead(nHardware::HEAD_WRITE);
   
-  read_head.Adjust();
-  write_head.Adjust();
+  read_head.QuickAdjust(m_memory.GetSize());
+  write_head.QuickAdjust(m_memory.GetSize());
   
   // Do mutations.
   cInstruction read_inst = read_head.GetInst();
@@ -6143,9 +6141,9 @@
   if (m_organism->TestCopyUniform(ctx)) doUniformCopyMutation(ctx, write_head);
   if (m_organism->TestCopySlip(ctx)) {
     if (m_slip_read_head) {
-      read_head.Set(ctx.GetRandom().GetInt(read_head.GetMemory().GetSize()));
+      read_head.Set(ctx.GetRandom().GetInt(m_memory.GetSize()));
     } else 
-      doSlipMutation(ctx, write_head.GetMemory(), write_head.GetPosition());
+      doSlipMutation(ctx, m_memory, write_head.GetPosition());
   }
 	m_organism->AttemptHGTInsertion(ctx);
 
@@ -6160,8 +6158,8 @@
   cHeadCPU & read_head = GetHead(nHardware::HEAD_READ);
   cHeadCPU & write_head = GetHead(nHardware::HEAD_WRITE);
   
-  read_head.Adjust();
-  write_head.Adjust();
+  read_head.QuickAdjust(m_memory.GetSize());
+  write_head.QuickAdjust(m_memory.GetSize());
   
   // Do mutations.
   cInstruction read_inst = read_head.GetInst();
@@ -6180,9 +6178,9 @@
   if (ctx.GetRandom().P(m_organism->GetCopyUniformProb() / reduction)) doUniformCopyMutation(ctx, write_head);
   if (ctx.GetRandom().P(m_organism->GetCopySlipProb() / reduction)) {
     if (m_slip_read_head) {
-      read_head.Set(ctx.GetRandom().GetInt(read_head.GetMemory().GetSize()));
+      read_head.Set(ctx.GetRandom().GetInt(m_memory.GetSize()));
     } else 
-      doSlipMutation(ctx, write_head.GetMemory(), write_head.GetPosition());
+      doSlipMutation(ctx, m_memory, write_head.GetPosition());
   }
   
   read_head.Advance();

Modified: development/source/cpu/cHardwareExperimental.cc
===================================================================
--- development/source/cpu/cHardwareExperimental.cc	2009-09-16 18:41:38 UTC (rev 3407)
+++ development/source/cpu/cHardwareExperimental.cc	2009-09-16 20:20:14 UTC (rev 3408)
@@ -328,7 +328,7 @@
     
     m_advance_ip = true;
     cHeadCPU& ip = m_threads[m_cur_thread].heads[nHardware::HEAD_IP];
-    ip.Adjust();
+    ip.QuickAdjust(m_memory.GetSize());
     
 #if BREAKPOINTS
     if (ip.FlagBreakpoint()) {
@@ -551,7 +551,7 @@
   // Make sure the label is of size > 0.
   if (search_label.GetSize() == 0) return ip;
 
-  cCPUMemory& memory = ip.GetMemory();
+  cCPUMemory& memory = m_memory;
   int pos = 0;
   
   while (pos < memory.GetSize()) {
@@ -700,7 +700,7 @@
 {
   for (int i = 0; i < m_threads.GetSize(); i++) {
     for (int j = 0; j < NUM_HEADS; j++) {
-      m_threads[i].heads[j].Adjust();
+      m_threads[i].heads[j].QuickAdjust(m_memory.GetSize());
     }
   }
 }
@@ -1392,7 +1392,7 @@
   const int dst = FindModifiedRegister(REG_BX);
   
   const int head_id = FindModifiedHead(nHardware::HEAD_READ);
-  GetHead(head_id).Adjust();
+  GetHead(head_id).QuickAdjust(m_memory.GetSize());
   
   // Mutations only occur on the read, for the moment.
   int read_inst = 0;
@@ -1405,7 +1405,7 @@
   ReadInst(read_inst);
   
   if (m_slip_read_head && m_organism->TestCopySlip(ctx))
-    GetHead(head_id).Set(ctx.GetRandom().GetInt(GetHead(head_id).GetMemory().GetSize()));
+    GetHead(head_id).Set(ctx.GetRandom().GetInt(m_memory.GetSize()));
   
   GetHead(head_id).Advance();
   return true;
@@ -1417,7 +1417,7 @@
   const int head_id = FindModifiedHead(nHardware::HEAD_WRITE);
   cHeadCPU& active_head = GetHead(head_id);
   
-  active_head.Adjust();
+  active_head.QuickAdjust(m_memory.GetSize());
   
   int value = m_threads[m_cur_thread].reg[src].value;
   if (value < 0 || value >= m_inst_set->GetSize()) value = 0;
@@ -1429,7 +1429,7 @@
   if (m_organism->TestCopyDel(ctx)) active_head.RemoveInst();
   if (m_organism->TestCopyUniform(ctx)) doUniformCopyMutation(ctx, active_head);
   if (!m_slip_read_head && m_organism->TestCopySlip(ctx)) 
-    doSlipMutation(ctx, active_head.GetMemory(), active_head.GetPosition());
+    doSlipMutation(ctx, m_memory, active_head.GetPosition());
   
   // Advance the head after write...
   active_head++;
@@ -1442,8 +1442,8 @@
   cHeadCPU& read_head = GetHead(nHardware::HEAD_READ);
   cHeadCPU& write_head = GetHead(nHardware::HEAD_WRITE);
   
-  read_head.Adjust();
-  write_head.Adjust();
+  read_head.QuickAdjust(m_memory.GetSize());
+  write_head.QuickAdjust(m_memory.GetSize());
   
   // Do mutations.
   cInstruction read_inst = read_head.GetInst();
@@ -1462,9 +1462,9 @@
   if (m_organism->TestCopyUniform(ctx)) doUniformCopyMutation(ctx, write_head);
   if (m_organism->TestCopySlip(ctx)) {
     if (m_slip_read_head) {
-      read_head.Set(ctx.GetRandom().GetInt(read_head.GetMemory().GetSize()));
+      read_head.Set(ctx.GetRandom().GetInt(m_memory.GetSize()));
     } else 
-      doSlipMutation(ctx, write_head.GetMemory(), write_head.GetPosition());
+      doSlipMutation(ctx, m_memory, write_head.GetPosition());
   }
   
   read_head.Advance();

Modified: development/source/cpu/cHeadCPU.cc
===================================================================
--- development/source/cpu/cHeadCPU.cc	2009-09-16 18:41:38 UTC (rev 3407)
+++ development/source/cpu/cHeadCPU.cc	2009-09-16 20:20:14 UTC (rev 3408)
@@ -28,13 +28,13 @@
 #include <cassert>
 
 
-void cHeadCPU::Adjust()
+void cHeadCPU::fullAdjust(int mem_size)
 {
   assert(m_mem_space >= 0);
   // Ensure that m_mem_space is valid
   if (m_mem_space != 0 && m_mem_space >= m_hardware->GetNumMemSpaces()) m_mem_space %= m_hardware->GetNumMemSpaces();
   
-  const int mem_size = GetMemSize();
+  if (mem_size < 0) mem_size = GetMemSize();
   
   // If we are still in range, stop here!
   if (m_position >= 0 && m_position < mem_size) return;

Modified: development/source/cpu/cHeadCPU.h
===================================================================
--- development/source/cpu/cHeadCPU.h	2009-09-16 18:41:38 UTC (rev 3407)
+++ development/source/cpu/cHeadCPU.h	2009-09-16 20:20:14 UTC (rev 3408)
@@ -54,6 +54,8 @@
   cHardwareBase* m_hardware;
   int m_position;
   int m_mem_space;
+  
+  void fullAdjust(int mem_size = -1);
 
   int FindLabel_Forward(const cCodeLabel& search_label, const cGenome& search_mem, int pos);
   int FindLabel_Backward(const cCodeLabel& search_label, const cGenome& search_mem, int pos);
@@ -68,7 +70,8 @@
   inline cCPUMemory& GetMemory() { return m_hardware->GetMemory(m_mem_space); }
   inline int GetMemSize() const { return m_hardware->GetMemSize(m_mem_space); }
   
-  void Adjust();
+  inline void Adjust() { if (m_mem_space != 0 || m_position < 0 || m_position >= GetMemSize()) fullAdjust(); }
+  inline void QuickAdjust(int msize) { if (m_mem_space != 0 || m_position < 0 || m_position >= msize) fullAdjust(msize); }
   inline void Reset(cHardwareBase* hw, int ms = 0) { m_hardware = hw; m_position = 0; m_mem_space = ms; }
   
   inline int GetMemSpace() const { return m_mem_space; }

Modified: development/source/main/cAvidaContext.h
===================================================================
--- development/source/main/cAvidaContext.h	2009-09-16 18:41:38 UTC (rev 3407)
+++ development/source/main/cAvidaContext.h	2009-09-16 20:20:14 UTC (rev 3408)
@@ -47,10 +47,11 @@
   cRandom* m_rng;
   bool m_analyze;
   bool m_testing;
+  bool m_org_faults;
   
 public:
-  cAvidaContext(cRandom& rng) : m_rng(&rng), m_analyze(false), m_testing(false) { ; }
-  cAvidaContext(cRandom* rng) : m_rng(rng), m_analyze(false), m_testing(false) { ; }
+  cAvidaContext(cRandom& rng) : m_rng(&rng), m_analyze(false), m_testing(false), m_org_faults(false) { ; }
+  cAvidaContext(cRandom* rng) : m_rng(rng), m_analyze(false), m_testing(false), m_org_faults(false) { ; }
   ~cAvidaContext() { ; }
   
   void SetRandom(cRandom& rng) { m_rng = &rng; }  
@@ -64,6 +65,10 @@
   void SetTestMode()   { m_testing = true; }   //@MRR  Some modifications I've made need to distinguish
   void ClearTestMode() { m_testing = false; }  //      when we're running a genotype through a test-cpu
   bool GetTestMode()   { return m_testing; }   //      versus when we're not when dealing with reactions rewards.
+
+  void EnableOrgFaultReporting() { m_org_faults = true; }
+  void DisableOrgFaultReporting() { m_org_faults = false; }
+  bool OrgFaultReporting() { return m_org_faults; }
 };
 
 #endif

Modified: development/source/targets/avida-viewer/cTextViewerDriver.cc
===================================================================
--- development/source/targets/avida-viewer/cTextViewerDriver.cc	2009-09-16 18:41:38 UTC (rev 3407)
+++ development/source/targets/avida-viewer/cTextViewerDriver.cc	2009-09-16 20:20:14 UTC (rev 3408)
@@ -70,6 +70,7 @@
   const double point_mut_prob = m_world->GetConfig().POINT_MUT_PROB.Get();
   
   cAvidaContext ctx(m_world->GetRandom());
+  ctx.EnableOrgFaultReporting();
   
   while (!m_done) {
     if (cChangeList* change_list = population.GetChangeList()) {




More information about the Avida-cvs mailing list