用于预先计算查找表和“分支预测”的设计模式

时间:2014-02-08 08:24:21

标签: c++ events event-handling conditional-statements lookup

我有一个看起来像这样的程序:

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所有可能EventTypeA的查找表,并且我有一个新的multiplier {1}},因此我可以使用查找替换intermediateResultEventBHandler的计算。

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

我的问题是,只有EventTypeA频繁发生且EventTypeB很少发生时才会表现良好。

在几个连续EventTypeB出现的情况下,比我预先计算查找表的速度快,我想过早地终止预计算并切换回原始方法。有干净的方法吗?

2 个答案:

答案 0 :(得分:1)

您可以选择更新计算中间结果的公式:

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

现在第一个结果将在0-10范围内,乘数本身也在同一范围内。现在,您可以轻松地为值设置10x10查找表。虽然使用上面的公式,实际计算本身并不是次优的。

答案 1 :(得分:1)

您可以预先计算一次0..9 * 0..100000值。 (你希望每次EventAHandler完成该工作的十分之一......)

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

如果预先计算的数组不适合内存,则可以使用数据库。

EventAHandler在检索部分数组时取消设置标志,并在准备好时设置标志。 如果flag没有准备好,EventBHandler计算值,否则使用查找表。