1

对于一个爱好解释器项目,我正在寻找有关任务同步的性能相关问题的建议。调度程序必须将新的绿色任务映射到实际任务,每个实际任务都有自己的绿色任务链表。

问题:如何以尽可能少的开销将绿色任务的添加同步到正在运行的实际任务?在早期的测试中,我发现将链表设置为受保护对象会极大地减慢从其自身实际任务中对其的访问速度。为了让您了解当前单任务版本中的解释器循环有多紧凑:

while not Is_Empty (Global_State.GTasks) loop
   Current_Task := Next (Global_State.GTasks);
   Global_State.Pram (Current_Task.PC).all (Global_State, Current_Task);
   Current_Task.PC := Current_Task.PC + 1;
   Update (Global_State.GTasks, Current_Task);
end loop;

(更新仍然是副本,但我以后可以摆脱它。)

我的测试表明,即使对这个循环进行最小的更改也会极大地减慢解释速度。想象一下,GTasks 不是在 Global_State 中,而是作为局部变量驻留在执行此循环的任务中。当调度程序从运行此循环的任务外部添加新的 GTask 时,我需要同步对 GTasks 的访问。

在这种情况下你会推荐什么?

4

1 回答 1

2

(以下内容取决于我对问题的合理理解。)

如果可以继续提出“GTasks 作为任务中的局部变量”猜想,那么也许结合条件接受可能会起作用——我不知道性能会受到什么影响,这只是一个想法。

while not Is_Empty (GTasks) loop
   Current_Task := Next (GTasks);
   Global_State.Pram (Current_Task.PC).all (Global_State, Current_Task);
   Current_Task.PC := Current_Task.PC + 1;
   Update (GTasks, Current_Task);

   select
      accept Accept_New_Task(Green_Task : Green_Task_Type) do
         Append(GTasks, Green_Task);
      end Accept_New_Task;
   else
      null;
   end select;
end loop;

或者也许只是定期检查新任务,例如,每增加这么多 PC?(同样,对性能影响没有任何承诺。)

while not Is_Empty (GTasks) loop
   Current_Task := Next (GTasks);
   Global_State.Pram (Current_Task.PC).all (Global_State, Current_Task);
   Current_Task.PC := Current_Task.PC + 1;
   Update (GTasks, Current_Task);

   if PC_Increments = Check_For_New_Tasks then
      select
         accept Accept_New_Task(Green_Task : Green_Task_Type) do
            Append(GTasks, Green_Task);
         end Accept_New_Task;
      else
         null;
      end select;
      PC_Increments := 0;
   else
      PC_Increments := PC_Increments + 1;
   end if;
end loop;
于 2013-03-11T19:56:03.507 回答