как предложить gcc компилятор более вероятное отделение

Пример:

if (almost_always_false_condition) {
       // do something
}

Есть ли способ предложить компилятор, который в 99%-м условии будет ложным. Вычисление условия берет ~60 циклов, которые будут проверены, и оно не может быть вычислено во время компиляции самим компилятором.

(gcc 4.3)

9
задан Karol 25 January 2010 в 15:54
поделиться

4 ответа

Если вы хотите предложить GCC, что условие, вероятно, будет иметь заданное значение как подсказку для аранжировки потока кода, вы должны использовать __ STOVELIN_EXPECT () :

if (__builtin_expect(almost_always_false_condition,0)) {
   // do something
}

Тем не менее, звучит так, как вы хотите найти способ избежать оценки состояния, который __ STOVELS_EXPECT () не будет. Есть ли способ, которым вы можете быстро приблизить состояние, и только выполнить полную проверку, когда приближение верно:

if (__builtin_expect(fastCheckThatIsTrueIfFullConditionIsTrue,0)) {
    // most of the time, we don't even get to here, so you don't need
    // to evaluate the condition
    if (almostAlwaysFalseCondition) {
        // do something
    }
}

Можете ли вы рассказать нам больше о том, что это состояние?

10
ответ дан 4 December 2019 в 13:47
поделиться

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

if (a == 5 && somethingexpensive())
{
   ...
}

С момента вычисления A == 5 дешевле, чем что-тоэксплуатация () , и если оно почти всегда FALSE , вы должны запустить его первым, что позволяет избежать оценки Статья , что оговорное .

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

static int result = doevalfunctiononlyonce();

if (result)
{
   ....    
}

Таким образом, вы сократили стоимость , если к простому поиску памяти.

Если условие меняет только изменения в ответ на действие в другой процедуре, вы можете обновить глобальную процедуру:

int condition;

void appendToList(int a)
{
   list.append(a);
   if (list.somethingexpensive())
   {
     condition = true;
   } else
   {
     condition = false;
   }
}

void someotherfunction()
{
  // if (list.somethingexpensive())
  if (condition)
  {
    ...
  }
}

Это полезно, если Comertherfunction называется большим количеством Функция AppendTolist .

3
ответ дан 4 December 2019 в 13:47
поделиться

Документация предполагает, что GCC делает (или может) выполнять оптимизацию, ориентированную на профиль. Это не то, что я когда-либо пытался сделать с GCC, поэтому не может предоставить никаких дополнительных советов, это может быть стоить вашего во время удара Google.

0
ответ дан 4 December 2019 в 13:47
поделиться

Прежде всего, сколько циклов проводится в , а также пункт или в другом месте в программе? Если вы выполните StackShots , вы тратите ли вы как минимум 10% вашего времени в этом тесте? Если нет, там, вероятно, больше проблем, вы должны посмотреть сначала.

Во-вторых, если вы тратите> 10% времени в этом тесте, вы должны посмотреть, как можно скорее настроить алгоритм, чтобы иметь точки принятия решений, ближе к 50-50 вероятности. Оччество принятия решений 50-50 дает 1 бит информации, когда она выполняется, в то время как начальник принятия решения 99-1 дает только около 0,07 бита. * (Т. Е. Это не говорит вам много, поэтому это неэффективное использование циклов ЦП. ) Пример этого явления - это если вы сравните линейный поиск с двоичным поиском.

* Если у вас есть точка бинарного решения, а вероятности результатов A и B , выходной выход (энтропия) в битах - (A * Журнал (а) + b * log (b)) / log (2) .

2
ответ дан 4 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: