Шаблон проектирования для предварительных вычислений справочных таблиц и «прогнозирования ветвлений»

У меня есть программа, которая выглядит так:

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так что я могу заменить расчет intermediateResult в EventBHandler с поиском.

Основанием для этого является то, что мой EventBHandler чувствителен ко времени, в то время как EventAHandler нет, поэтому, когда EventTypeB прибывает позже, EventBHandler не должен выполнять int intermediateResult = (e.someOtherInt * multipler) % 10 + 1; (давайте представим, что это утверждение занимает гораздо больше тактов) и только для поиска.

Моя проблема в том, что он работает хорошо, только если EventTypeAпроисходят часто в то время как EventTypeBвстречаются редко.

В случаях, когда несколько последовательных EventTypeBЭто происходит быстрее, чем я могу предварительно вычислить таблицу поиска, я хочу преждевременно прекратить предварительные вычисления и вернуться к первоначальному подходу. Есть ли чистый способ сделать это?

0

Решение

У вас есть возможность обновить формулу для расчета промежуточных результатов как:

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

Теперь первый результат будет в диапазоне 0-10, а сам множитель также находится в том же диапазоне. Теперь вам будет легко иметь справочную таблицу 10×10 для значений. Хотя с приведенной выше формулой, фактический расчет сам по себе не будет таким неоптимальным.

1

Другие решения

Вы можете предварительно вычислить, как только 0..9 * 0..100000 ценности.
(Вы хотели EventAHandler делает 1/10 этой работы каждый раз …)

затем EventBHandler делает просто поиск.
EventAHandler не буду делать огромные вычисления каждый раз.

Если предварительно вычисленный массив не помещается в памяти, вы можете использовать базу данных.

EventAHandler снимает флажок при получении части массива и устанавливает флажок, когда готов.
EventBHandler вычисляет значение, если флаг не готов, иначе использует таблицу поиска.

1

По вопросам рекламы [email protected]