Если вы используете следующую конструкцию:
void log_some_stuff_implementation(Provider *pProvider, int x, int y, char const* str);
__inline void log_some_stuff(Provider *pProvider, int x, int y, char const* str)
{
if (__builtin_expect( pProvider != NULL, 0)) {
log_some_stuff_implementation(pProvider, x, y, str);
}
return;
}
GCC 4.5.2 с -O2
генерирует следующий код (по крайней мере, для моего простого теста) для вызова log_some_stuff()
:
// r0 already has the Provider* in it - r2 has a value that indicates whether
// r0 was loaded with a valid pointer or not
cmp r2, #0
ldrne r3, [r1, #0]
addne r1, r2, #1
ldrneb r2, [r3, #0] @ zero_extendqisi2
blne log_some_stuff_implementation
Таким образом, в общем случае (где Provider * равен NULL) используются 4 инструкции, но не выполняются из-за условия, но конвейер ARM не сбрасывается.Я думаю, что это, вероятно, примерно так же хорошо, как вы получите для общего случая, когда вы на самом деле не хотите, чтобы код ведения журнала запускался.
Я думаю, что ключ в том, что код, который на самом деле выполняет запись в журналвыполняется не в строке в отдельной функции, так что компилятор может разумно настроить и вызвать эту функцию в виде встроенной последовательности нескольких условно выполненных инструкций.Поскольку фактический код регистрации не нуждается в оптимизации, нет причин для его встраивания.Это не должно быть распространенным случаем, и, вероятно, это код, который будет выполнять какую-то реальную работу.Следовательно, накладные расходы на вызов функции должны быть приемлемыми (по крайней мере, это мое предположение).
Кстати, для моего простого теста генерируется та же самая последовательность кода (или, по сути, та же самая последовательность), даже если __builtin_expect()
опущен, однако я представляю, что в более сложных последовательностях, чем в моем простом тесте, встроенная программа может помочь компилятору.Поэтому я бы, вероятно, оставил это, но я бы также использовал более читаемые версии, такие как макросы ядра Linux:
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)