Невозможно сказать без конкретной системы. Разберите код и посмотрите, что вы получили. Оцените ваш код в конкретной системе. Это ключ к пониманию ручной оптимизации.
Как правило, есть много соображений. Размер слова данных процессора, набор команд, производительность оптимизатора компилятора, прогноз ветвления (если есть), кэш данных (если есть) и т. Д. И т. Д.
Чтобы код работал оптимально, независимо от размера слова данных, вы можете изменить uint8_t
на uint_fast8_t
. То есть, если вам не нужно ровно 8 бит, оставьте это как uint8_t
.
Использование кэша может быть, а может и не быть более эффективным, если задан цикл повышающего счета. В любом случае, развертывание цикла - это старый вид ручной оптимизации, который мы не должны использовать в современном программировании - компилятор способен выполнить этот вызов больше, чем программист.
Худшая проблема с кодом - многочисленные ветки. Это может вызвать узкое место.
Ваш код приводит к следующему машинному коду x86 gcc -O2
:
b2i:
cmp BYTE PTR [rdi+6], 0
movzx eax, BYTE PTR [rdi+7]
je .L2
add eax, 2
.L2:
cmp BYTE PTR [rdi+5], 0
je .L3
add eax, 4
.L3:
cmp BYTE PTR [rdi+4], 0
je .L4
add eax, 8
.L4:
cmp BYTE PTR [rdi+3], 0
je .L5
add eax, 16
.L5:
cmp BYTE PTR [rdi+2], 0
je .L6
add eax, 32
.L6:
cmp BYTE PTR [rdi+1], 0
je .L7
add eax, 64
.L7:
lea edx, [rax-128]
cmp BYTE PTR [rdi], 0
cmovne eax, edx
ret
Целая масса потенциально неэффективных ветвлений. Мы можем сделать код более быстрым и более читабельным, используя цикл:
uint8_t b2i (const bool bs[8])
{
uint8_t result = 0;
for(size_t i=0; i<8; i++)
{
result |= bs[8-1-i] << i;
}
return result;
}
(в идеале массив bool должен сначала располагаться из LSB, но это изменило бы значение кода по сравнению с оригиналом)
Что дает этот машинный код вместо:
b2i:
lea rsi, [rdi-8]
mov rax, rdi
xor r8d, r8d
.L2:
movzx edx, BYTE PTR [rax+7]
mov ecx, edi
sub ecx, eax
sub rax, 1
sal edx, cl
or r8d, edx
cmp rax, rsi
jne .L2
mov eax, r8d
ret
Больше инструкций, но меньше ветвлений. Вероятно, он будет работать лучше, чем ваш код на x86 и других высокопроизводительных процессорах с предсказанием ветвлений и кэшем инструкций. Но хуже, чем ваш код на 8-битном микроконтроллере, где учитывается только общее количество инструкций.