2014-02-08 48 views
0

我有一个程序,看起来像这样:设计模式和“分支预测”

struct EventTypeA { 
    int someInt;  // random between 0 and 9 
}; 

struct EventTypeB { 
    int someOtherInt; // random between 0 and 100000 
}; 

int EventAHandler(EventTypeA e) { 
    // Updates multiplier 
    static int multipler = e.someInt; 
    return multiplier; 
} 

double EventBHandler(EventTypeB e) { 
    /* This is a simple example for illustration, the actual intermediate 
     calculation takes up much more computational time than this */ 
    int intermediateResult = (e.someOtherInt * multipler) % 10 + 1; 

    if (intermediateResult <= 3) { DoAction1(); } 
    if (intermediateResult >= 7) { DoAction2(); } 
} 

... 
... 

void SomeMethodWithinSomeClass() { 
    while (true) { 
     // Listen for events of type A and B 
     // if EventTypeA occurs, invoke EventAHandler 
     // if EventTypeB occurs, invoke EventBHandler 
    } 
} 

我想有EventAHandler预先计算的intermediateResult的查找表来查找所有可能的EventTypeB.someOtherInt' s分别是一个EventTypeA到达,我有一个新的multiplier时间,所以我可以用查找替换EventBHandlerintermediateResult计算。

这样做的原因是,我EventBHandler是时间敏感,而EventAHandler是不是:所以当一个EventTypeB后到达,EventBHandler不必执行int intermediateResult = (e.someOtherInt * multipler) % 10 + 1;(我们假设这种说法占用了更多的时钟周期)和只需要查找。

我的问题是,如果EventTypeA频繁发生,而EventTypeB很少发生,它只会表现良好。

在发生几个连续的EventTypeB的情况下,比我可以预先计算查找表的速度快,我想要提前终止预计算并切换回原始方法。有没有一种干净的方式来做到这一点?

回答

1

你必须更新您的公式计算中间结果的一个选项:

intermediate_result = ((e.someOtherInt) % 10) * multiplier + 1 

现在的第一个结果是在0-10范围内和倍频本身也是在同一范围内。现在应该很容易为这些值设置一个10x10查找表。虽然使用上述公式,但实际计算本身并不会是次优的。

+0

我一声给予好评的聪明的数学运算,而不是最终的答案,我虽然期待,因为实际的中间计算比这个(类似多次调用线性代数库和大型矩阵操作)更计算昂贵。这是我的错,因为我没有澄清,所以我会更新这个问题。谢谢! – elleciel

1

您可以预先计算一旦0..9 * 0..100000值。 (你想要EventAHandler每次都会做1/10的工作...)

然后EventBHandler只是查找。 EventAHandler每次都不会做大量的计算。

如果-computated预阵列不会装入内存,你可以使用一个数据库。

EventAHandler检索所述阵列的一部分时,可清除一个标志并设置一个标志时准备好。 EventBHandler如果标志未准备好,则计算值,否则使用查找表。