[Avida-SVN] r2311 - in development/source: cpu drivers main

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Thu Feb 7 20:20:55 PST 2008


Author: brysonda
Date: 2008-02-07 23:20:55 -0500 (Thu, 07 Feb 2008)
New Revision: 2311

Modified:
   development/source/cpu/cHardwareBase.h
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareCPU.h
   development/source/cpu/cHardwareExperimental.cc
   development/source/cpu/cHardwareExperimental.h
   development/source/cpu/cHardwareManager.cc
   development/source/cpu/cHardwareManager.h
   development/source/drivers/cDefaultRunDriver.cc
   development/source/main/cAvidaConfig.h
   development/source/main/cPopulation.cc
   development/source/main/cPopulation.h
Log:
Add configuration toggle to disable speculative execution. Separate ProcessStep into two functions, one speculative, one not.  The correct method is selected in the driver object based on settings.

Modified: development/source/cpu/cHardwareBase.h
===================================================================
--- development/source/cpu/cHardwareBase.h	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/cpu/cHardwareBase.h	2008-02-08 04:20:55 UTC (rev 2311)
@@ -68,8 +68,6 @@
   bool m_has_ft_costs;
   bool m_has_energy_costs;
   
-  bool m_supports_speculative;
-  
 
   virtual int GetExecutedSize(const int parent_size);
   virtual int GetCopiedSize(const int parent_size, const int child_size) = 0;  
@@ -99,7 +97,7 @@
   cHardwareBase(cWorld* world, cOrganism* in_organism, cInstSet* inst_set)
     : m_world(world), organism(in_organism), m_inst_set(inst_set), m_tracer(NULL)
     , m_has_costs(inst_set->HasCosts()), m_has_ft_costs(inst_set->HasFTCosts())
-    , m_has_energy_costs(m_inst_set->HasEnergyCosts()), m_supports_speculative(false)
+    , m_has_energy_costs(m_inst_set->HasEnergyCosts())
   {
     m_has_any_costs = (m_has_costs | m_has_ft_costs | m_has_energy_costs);
     assert(organism != NULL);
@@ -119,9 +117,6 @@
   unsigned Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier = 1.0, const int maxmut = INT_MAX);
   bool Divide_TestFitnessMeasures(cAvidaContext& ctx);
   
-  inline bool SupportsSpeculative() const { return m_supports_speculative; }
-  
-  
   // --------  Helper methods  --------
   virtual int GetType() const = 0;
   virtual bool OK() = 0;

Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/cpu/cHardwareCPU.cc	2008-02-08 04:20:55 UTC (rev 2311)
@@ -412,9 +412,14 @@
   m_functions = s_inst_slib->GetFunctions();
   /**/
   
-  m_supports_speculative = true;
   m_spec_die = false;
   
+  m_thread_slicing_parallel = (m_world->GetConfig().THREAD_SLICING_METHOD.Get() == 1);
+  m_no_cpu_cycle_time = m_world->GetConfig().NO_CPU_CYCLE_TIME.Get();
+  
+  m_promoters_enabled = m_world->GetConfig().PROMOTERS_ENABLED.Get();
+  m_constituative_regulation = m_world->GetConfig().CONSTITUTIVE_REGULATION.Get();
+  
   m_memory = in_organism->GetGenome();  // Initialize memory...
   Reset();                            // Setup the rest of the hardware...
 }
@@ -513,7 +518,7 @@
 
 bool cHardwareCPU::SingleProcess(cAvidaContext& ctx, bool speculative)
 {
-  assert(!speculative || (speculative && m_world->GetConfig().THREAD_SLICING_METHOD.Get() != 1));
+  assert(!speculative || (speculative && !m_thread_slicing_parallel));
 
   int last_IP_pos = IP().GetPosition();
   
@@ -530,7 +535,7 @@
   cPhenotype& phenotype = organism->GetPhenotype();
   
   // First instruction - check whether we should be starting at a promoter, when enabled.
-  if (phenotype.GetCPUCyclesUsed() == 0 && m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) Inst_Terminate(ctx);
+  if (phenotype.GetCPUCyclesUsed() == 0 && m_promoters_enabled) Inst_Terminate(ctx);
   
   // Count the cpu cycles used
   phenotype.IncCPUCyclesUsed();
@@ -540,7 +545,7 @@
   
   // If we have threads turned on and we executed each thread in a single
   // timestep, adjust the number of instructions executed accordingly.
-  const int num_inst_exec = (m_world->GetConfig().THREAD_SLICING_METHOD.Get() == 1) ? num_threads : 1;
+  const int num_inst_exec = m_thread_slicing_parallel ? num_threads : 1;
   
   for (int i = 0; i < num_inst_exec; i++) {
     // Setup the hardware for the next instruction to be executed.
@@ -548,10 +553,11 @@
     if (m_cur_thread >= num_threads) m_cur_thread = 0;
     
     m_advance_ip = true;
-    IP().Adjust();
+    cHeadCPU& ip = m_threads[m_cur_thread].heads[nHardware::HEAD_IP];
+    ip.Adjust();
     
 #if BREAKPOINTS
-    if (IP().FlagBreakpoint()) {
+    if (ip.FlagBreakpoint()) {
       organism->DoBreakpoint();
     }
 #endif
@@ -560,13 +566,13 @@
     if (m_tracer != NULL) m_tracer->TraceHardware(*this);
     
     // Find the instruction to be executed
-    const cInstruction& cur_inst = IP().GetInst();
+    const cInstruction& cur_inst = ip.GetInst();
     
     if (speculative && (m_spec_die || m_inst_set->ShouldStall(cur_inst))) {
       // Speculative instruction reject, flush and return
       m_cur_thread = last_thread;
       phenotype.DecCPUCyclesUsed();
-      if (!m_world->GetConfig().NO_CPU_CYCLE_TIME.Get()) phenotype.IncTimeUsed(-1);
+      if (!m_no_cpu_cycle_time) phenotype.IncTimeUsed(-1);
       organism->SetRunning(false);
       return false;
     }
@@ -576,17 +582,11 @@
     if (m_has_any_costs) exec = SingleProcess_PayCosts(ctx, cur_inst);
 
     // Constitutive regulation applied here
-    if (m_world->GetConfig().CONSTITUTIVE_REGULATION.Get() == 1) {
-      Inst_SenseRegulate(ctx);
-    }
-    
+    if (m_constituative_regulation) Inst_SenseRegulate(ctx); 
+
     // If there are no active promoters and a certain mode is set, then don't execute any further instructions
-    if ((m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) 
-      && (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2) 
-      && (m_promoter_index == -1) ) { 
-      exec = false;
-    }
-    
+    if (m_promoters_enabled && m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2 && m_promoter_index == -1) exec = false;
+  
     // Now execute the instruction...
     if (exec == true) {
       // NOTE: This call based on the cur_inst must occur prior to instruction
@@ -595,32 +595,28 @@
       const int time_cost = m_inst_set->GetAddlTimeCost(cur_inst);
 
       // Prob of exec (moved from SingleProcess_PayCosts so that we advance IP after a fail)
-      if ( m_inst_set->GetProbFail(cur_inst) > 0.0 ) {
+      if (m_inst_set->GetProbFail(cur_inst) > 0.0) {
         exec = !( ctx.GetRandom().P(m_inst_set->GetProbFail(cur_inst)) );
       }
       
-      //Add to the promoter inst executed count before executing the inst (in case it is a terminator)
-      if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) {
-        m_threads[m_cur_thread].IncPromoterInstExecuted();
-      }
+      // Add to the promoter inst executed count before executing the inst (in case it is a terminator)
+      if (m_promoters_enabled) m_threads[m_cur_thread].IncPromoterInstExecuted();
 
       if (exec == true) SingleProcess_ExecuteInst(ctx, cur_inst);
       
       // Some instruction (such as jump) may turn m_advance_ip off.  Usually
       // we now want to move to the next instruction in the memory.
-      if (m_advance_ip == true) IP().Advance();
+      if (m_advance_ip == true) ip.Advance();
       
       // Pay the time cost of the instruction now
       phenotype.IncTimeUsed(time_cost);
             
       // In the promoter model, we may force termination after a certain number of inst have been executed
-      if ( m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1 )
-      {
+      if (m_promoters_enabled) {
         const double processivity = m_world->GetConfig().PROMOTER_PROCESSIVITY.Get();
-        if ( ctx.GetRandom().P(1-processivity) ) 
+        if (ctx.GetRandom().P(1 - processivity)) Inst_Terminate(ctx);
+        if (m_world->GetConfig().PROMOTER_INST_MAX.Get() && (m_threads[m_cur_thread].GetPromoterInstExecuted() >= m_world->GetConfig().PROMOTER_INST_MAX.Get())) 
           Inst_Terminate(ctx);
-        if ( m_world->GetConfig().PROMOTER_INST_MAX.Get() && (m_threads[m_cur_thread].GetPromoterInstExecuted() >= m_world->GetConfig().PROMOTER_INST_MAX.Get()) ) 
-          Inst_Terminate(ctx);
       }
 
     } // if exec
@@ -636,7 +632,7 @@
   if (!speculative && phenotype.GetToDelete()) m_spec_die = true;
   
   // Note: if organism just died, this will NOT let it repro.
-  CheckImplicitRepro(ctx, last_IP_pos > IP().GetPosition());
+  CheckImplicitRepro(ctx, last_IP_pos > m_threads[m_cur_thread].heads[nHardware::HEAD_IP].GetPosition());
   
   organism->SetRunning(false);
   

Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/cpu/cHardwareCPU.h	2008-02-08 04:20:55 UTC (rev 2311)
@@ -137,10 +137,18 @@
   int m_cur_thread;
 
   // Flags...
-  bool m_mal_active;         // Has an allocate occured since last divide?
-  bool m_advance_ip;         // Should the IP advance after this instruction?
-  bool m_executedmatchstrings;	// Have we already executed the match strings instruction?
-  bool m_spec_die;
+  struct {
+    bool m_mal_active:1;         // Has an allocate occured since last divide?
+    bool m_advance_ip:1;         // Should the IP advance after this instruction?
+    bool m_executedmatchstrings:1;	// Have we already executed the match strings instruction?
+    bool m_spec_die:1;
+    
+    bool m_thread_slicing_parallel:1;
+    bool m_no_cpu_cycle_time:1;
+    
+    bool m_promoters_enabled:1;
+    bool m_constituative_regulation:1;
+  };
 
   // <-- Promoter model
   int m_promoter_index;       //site to begin looking for the next active promoter from

Modified: development/source/cpu/cHardwareExperimental.cc
===================================================================
--- development/source/cpu/cHardwareExperimental.cc	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/cpu/cHardwareExperimental.cc	2008-02-08 04:20:55 UTC (rev 2311)
@@ -203,9 +203,14 @@
   m_functions = s_inst_slib->GetFunctions();
   /**/
   
-  m_supports_speculative = true;
   m_spec_die = false;
 
+  m_thread_slicing_parallel = (m_world->GetConfig().THREAD_SLICING_METHOD.Get() == 1);
+  m_no_cpu_cycle_time = m_world->GetConfig().NO_CPU_CYCLE_TIME.Get();
+  
+  m_promoters_enabled = m_world->GetConfig().PROMOTERS_ENABLED.Get();
+  m_constituative_regulation = m_world->GetConfig().CONSTITUTIVE_REGULATION.Get();
+  
   m_memory = in_organism->GetGenome();  // Initialize memory...
   Reset();                            // Setup the rest of the hardware...
 }
@@ -301,7 +306,7 @@
 
 bool cHardwareExperimental::SingleProcess(cAvidaContext& ctx, bool speculative)
 {
-  assert(!speculative || (speculative && m_world->GetConfig().THREAD_SLICING_METHOD.Get() != 1));
+  assert(!speculative || (speculative && !m_thread_slicing_parallel));
   
   // Mark this organism as running...
   organism->SetRunning(true);
@@ -315,10 +320,10 @@
   cPhenotype& phenotype = organism->GetPhenotype();
 
   // First instruction - check whether we should be starting at a promoter, when enabled.
-  if (phenotype.GetCPUCyclesUsed() == 0 && m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) Inst_Terminate(ctx);
+  if (phenotype.GetCPUCyclesUsed() == 0 && m_promoters_enabled) Inst_Terminate(ctx);
   
   phenotype.IncCPUCyclesUsed();
-  if (!m_world->GetConfig().NO_CPU_CYCLE_TIME.Get()) phenotype.IncTimeUsed();
+  if (!m_no_cpu_cycle_time) phenotype.IncTimeUsed();
 
   const int num_threads = m_threads.GetSize();
   
@@ -332,10 +337,11 @@
     if (m_cur_thread >= num_threads) m_cur_thread = 0;
     
     m_advance_ip = true;
-    IP().Adjust();
+    cHeadCPU& ip = m_threads[m_cur_thread].heads[nHardware::HEAD_IP];
+    ip.Adjust();
     
 #if BREAKPOINTS
-    if (IP().FlagBreakpoint()) {
+    if (ip.FlagBreakpoint()) {
       organism->DoBreakpoint();
     }
 #endif
@@ -344,13 +350,13 @@
     if (m_tracer != NULL) m_tracer->TraceHardware(*this);
     
     // Find the instruction to be executed
-    const cInstruction& cur_inst = IP().GetInst();
+    const cInstruction& cur_inst = ip.GetInst();
     
     if (speculative && (m_spec_die || m_inst_set->ShouldStall(cur_inst))) {
       // Speculative instruction reject, flush and return
       m_cur_thread = last_thread;
       phenotype.DecCPUCyclesUsed();
-      if (!m_world->GetConfig().NO_CPU_CYCLE_TIME.Get()) phenotype.IncTimeUsed(-1);
+      if (!m_no_cpu_cycle_time) phenotype.IncTimeUsed(-1);
       organism->SetRunning(false);
       return false;
     }
@@ -359,17 +365,12 @@
     bool exec = true;
     if (m_has_any_costs) exec = SingleProcess_PayCosts(ctx, cur_inst);
 
-    // Constitutive regulation applied here
-    if (m_world->GetConfig().CONSTITUTIVE_REGULATION.Get() == 1) {
-      Inst_SenseRegulate(ctx);
-    }
     
+    // Constitutive regulation applied here
+    if (m_constituative_regulation) Inst_SenseRegulate(ctx); 
+
     // If there are no active promoters and a certain mode is set, then don't execute any further instructions
-    if ((m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) 
-        && (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2) 
-        && (m_promoter_index == -1) ) { 
-      exec = false;
-    }
+    if (m_promoters_enabled && m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2 && m_promoter_index == -1) exec = false;
     
     // Now execute the instruction...
     if (exec == true) {
@@ -385,22 +386,19 @@
       }
       
       //Add to the promoter inst executed count before executing the inst (in case it is a terminator)
-      if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) {
-        m_threads[m_cur_thread].IncPromoterInstExecuted();
-      }
+      if (m_promoters_enabled) m_threads[m_cur_thread].IncPromoterInstExecuted();
       
       if (exec == true) SingleProcess_ExecuteInst(ctx, cur_inst);
       
       // Some instruction (such as jump) may turn m_advance_ip off.  Usually
       // we now want to move to the next instruction in the memory.
-      if (m_advance_ip == true) IP().Advance();
+      if (m_advance_ip == true) ip.Advance();
       
       // Pay the additional death_cost of the instruction now
       phenotype.IncTimeUsed(addl_time_cost);
 
       // In the promoter model, we may force termination after a certain number of inst have been executed
-      if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1)
-      {
+      if (m_promoters_enabled) {
         const double processivity = m_world->GetConfig().PROMOTER_PROCESSIVITY.Get();
         if (ctx.GetRandom().P(1 - processivity)) Inst_Terminate(ctx);
         if (m_world->GetConfig().PROMOTER_INST_MAX.Get() &&

Modified: development/source/cpu/cHardwareExperimental.h
===================================================================
--- development/source/cpu/cHardwareExperimental.h	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/cpu/cHardwareExperimental.h	2008-02-08 04:20:55 UTC (rev 2311)
@@ -142,12 +142,20 @@
   int m_cur_thread;
 
   // Flags...
-  bool m_mal_active;         // Has an allocate occured since last divide?
-  bool m_advance_ip;         // Should the IP advance after this instruction?
-  bool m_executedmatchstrings;	// Have we already executed the match strings instruction?
-  bool m_spec_die;
+  struct {
+    bool m_mal_active:1;         // Has an allocate occured since last divide?
+    bool m_advance_ip:1;         // Should the IP advance after this instruction?
+    bool m_executedmatchstrings:1;	// Have we already executed the match strings instruction?
+    bool m_spec_die:1;
+    
+    bool m_thread_slicing_parallel:1;
+    bool m_no_cpu_cycle_time:1;
+    
+    bool m_promoters_enabled:1;
+    bool m_constituative_regulation:1;
+  };
+  
 
-
   
   // <-- Promoter model
   int m_promoter_index;       //site to begin looking for the next active promoter from

Modified: development/source/cpu/cHardwareManager.cc
===================================================================
--- development/source/cpu/cHardwareManager.cc	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/cpu/cHardwareManager.cc	2008-02-08 04:20:55 UTC (rev 2311)
@@ -102,3 +102,16 @@
       return NULL;
   }
 }
+
+bool cHardwareManager::SupportsSpeculative()
+{
+  switch (m_type)
+  {
+    case HARDWARE_TYPE_CPU_ORIGINAL:      return true;
+    case HARDWARE_TYPE_CPU_SMT:           return false;
+    case HARDWARE_TYPE_CPU_TRANSSMT:      return false;
+    case HARDWARE_TYPE_CPU_EXPERIMENTAL:  return true;
+    case HARDWARE_TYPE_CPU_GX:            return false;
+    default:                              return false;
+  }
+}

Modified: development/source/cpu/cHardwareManager.h
===================================================================
--- development/source/cpu/cHardwareManager.h	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/cpu/cHardwareManager.h	2008-02-08 04:20:55 UTC (rev 2311)
@@ -66,6 +66,8 @@
 
   const cInstSet& GetInstSet() const { return *m_inst_set; }
   cInstSet& GetInstSet() { return *m_inst_set; }
+  
+  bool SupportsSpeculative();
 };
 
 

Modified: development/source/drivers/cDefaultRunDriver.cc
===================================================================
--- development/source/drivers/cDefaultRunDriver.cc	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/drivers/cDefaultRunDriver.cc	2008-02-08 04:20:55 UTC (rev 2311)
@@ -30,6 +30,7 @@
 #include "cDriverManager.h"
 #include "cGenotype.h"
 #include "cHardwareBase.h"
+#include "cHardwareManager.h"
 #include "cOrganism.h"
 #include "cPopulation.h"
 #include "cPopulationCell.h"
@@ -66,6 +67,12 @@
   const int ave_time_slice = m_world->GetConfig().AVE_TIME_SLICE.Get();
   const double point_mut_prob = m_world->GetConfig().POINT_MUT_PROB.Get();
   
+  void (cPopulation::*ActiveProcessStep)(cAvidaContext& ctx, double step_size, int cell_id) = &cPopulation::ProcessStep;
+  if (m_world->GetHardwareManager().SupportsSpeculative() && m_world->GetConfig().SPECULATIVE.Get() &&
+      m_world->GetConfig().THREAD_SLICING_METHOD.Get() != 1) {
+    ActiveProcessStep = &cPopulation::ProcessStepSpeculative;
+  }
+  
   cAvidaContext& ctx = m_world->GetDefaultContext();
 
   while (!m_done) {
@@ -102,7 +109,7 @@
         m_done = true;
         break;
       }
-      population.ProcessStep(ctx, step_size);
+      (population.*ActiveProcessStep)(ctx, step_size, population.ScheduleOrganism());
     }
     
     // end of update stats...

Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/main/cAvidaConfig.h	2008-02-08 04:20:55 UTC (rev 2311)
@@ -282,6 +282,7 @@
   CONFIG_ADD_VAR(WORLD_GEOMETRY, int, 2, "1 = Bounded Grid\n2 = Torus\n3 = Clique");
   CONFIG_ADD_VAR(RANDOM_SEED, int, 0, "Random number seed (0 for based on time)");
   CONFIG_ADD_VAR(HARDWARE_TYPE, int, 0, "0 = Original CPUs\n1 = New SMT CPUs\n2 = Transitional SMT\n3 = Experimental CPU\n4 = Gene Expression CPU");
+  CONFIG_ADD_VAR(SPECULATIVE, bool, 1, "Enable speculative execution");
   
   CONFIG_ADD_GROUP(CONFIG_FILE_GROUP, "Configuration Files");
   CONFIG_ADD_VAR(DATA_DIR, cString, "data", "Directory in which config files are found");

Modified: development/source/main/cPopulation.cc
===================================================================
--- development/source/main/cPopulation.cc	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/main/cPopulation.cc	2008-02-08 04:20:55 UTC (rev 2311)
@@ -2138,44 +2138,61 @@
 {
   assert(step_size > 0.0);
   assert(cell_id < cell_array.GetSize());
+  
   // If cell_id is negative, no cell could be found -- stop here.
   if (cell_id < 0) return;
+  
   cPopulationCell& cell = GetCell(cell_id);
   assert(cell.IsOccupied()); // Unoccupied cell getting processor time!
   cOrganism* cur_org = cell.GetOrganism();
 
+  cell.GetHardware()->SingleProcess(ctx);    
+  
+  if (cur_org->GetPhenotype().GetToDelete() == true) delete cur_org;
+
+  m_world->GetStats().IncExecuted();
+  resource_count.Update(step_size);
+  for(int i = 0; i < GetNumDemes(); i++) GetDeme(i).Update(step_size);
+}
+
+
+void cPopulation::ProcessStepSpeculative(cAvidaContext& ctx, double step_size, int cell_id)
+{
+  assert(step_size > 0.0);
+  assert(cell_id < cell_array.GetSize());
+  assert(m_world->GetHardwareManager().SupportsSpeculative());
+
+  // If cell_id is negative, no cell could be found -- stop here.
+  if (cell_id < 0) return;
+  
+  cPopulationCell& cell = GetCell(cell_id);
+  assert(cell.IsOccupied()); // Unoccupied cell getting processor time!
+  
+  cOrganism* cur_org = cell.GetOrganism();
   cHardwareBase* hw = cell.GetHardware();
   
-  if (hw->SupportsSpeculative()) {
-    if (cell.GetSpeculativeState()) {
-      // We have already executed this instruction, just decrement the counter
-      cell.DecSpeculative();
-    } else {
-      // Execute the actual instruction
-      if (hw->SingleProcess(ctx)) {      
-        // Speculatively execute additional instructions
-        int spec_count = 0;
-        while (spec_count < 32) {
-          if (hw->SingleProcess(ctx, true)) spec_count++;
-          else break;
-        }
-        cell.SetSpeculativeState(spec_count);
-        m_world->GetStats().AddSpeculative(spec_count);
+  if (cell.GetSpeculativeState()) {
+    // We have already executed this instruction, just decrement the counter
+    cell.DecSpeculative();
+  } else {
+    // Execute the actual instruction
+    if (hw->SingleProcess(ctx)) {
+      // Speculatively execute additional instructions
+      int spec_count = 0;
+      while (spec_count < 32) {
+        if (hw->SingleProcess(ctx, true)) spec_count++;
+        else break;
       }
+      cell.SetSpeculativeState(spec_count);
+      m_world->GetStats().AddSpeculative(spec_count);
     }
-  } else {
-    // Just execute the instruction
-    hw->SingleProcess(ctx);    
   }
   
-  if (cur_org->GetPhenotype().GetToDelete() == true) {
-    delete cur_org;
-  }
+  if (cur_org->GetPhenotype().GetToDelete() == true) delete cur_org;
+
   m_world->GetStats().IncExecuted();
   resource_count.Update(step_size);
-  for(int i = 0; i < GetNumDemes(); i++) {
-    GetDeme(i).Update(step_size);
-  }
+  for(int i = 0; i < GetNumDemes(); i++) GetDeme(i).Update(step_size);
 }
 
 

Modified: development/source/main/cPopulation.h
===================================================================
--- development/source/main/cPopulation.h	2008-02-07 21:21:15 UTC (rev 2310)
+++ development/source/main/cPopulation.h	2008-02-08 04:20:55 UTC (rev 2311)
@@ -227,7 +227,7 @@
   // Process a single organism one instruction...
   int ScheduleOrganism();          // Determine next organism to be processed.
   void ProcessStep(cAvidaContext& ctx, double step_size, int cell_id);
-  void ProcessStep(cAvidaContext& ctx, double step_size) { ProcessStep(ctx, step_size, ScheduleOrganism()); }
+  void ProcessStepSpeculative(cAvidaContext& ctx, double step_size, int cell_id);
 
   // Calculate the statistics from the most recent update.
   void CalcUpdateStats();




More information about the Avida-cvs mailing list