Возможна «собственная внутренняя» функция для x64 вместо встроенной сборки?

В настоящее время я экспериментирую с созданием высокооптимизированных многоразовых функций для моей библиотеки. Например, я пишу функцию «степень двойки» следующим образом:

template  
inline bool is_power_of_two( const IntType x )
{
    return (x != 0) && ((x & (x - 1)) == 0);
}

Это переносимая реализация с минимальным обслуживанием в виде встроенного шаблона C ++. Этот код компилируется VC ++ 2008 в следующий код с ветвями:

is_power_of_two PROC
    test    rcx, rcx
    je  SHORT $LN3@is_power_o
    lea rax, QWORD PTR [rcx-1]
    test    rax, rcx
    jne SHORT $LN3@is_power_o
    mov al, 1
    ret 0
$LN3@is_power_o:
    xor al, al
    ret 0
is_power_of_two ENDP

Я также нашел реализацию отсюда: «Битовый тиддлер» , который будет закодирован в ассемблере для x64 следующим образом:

is_power_of_two_fast PROC
    test rcx, rcx
    je  SHORT NotAPowerOfTwo
    lea rax, [rcx-1]
    and rax, rcx
    neg rax
    sbb rax, rax
    inc rax
    ret
NotAPowerOfTwo:
    xor rax, rax
    ret
is_power_of_two_fast ENDP

Я тестировал обе подпрограммы, написанные отдельно от C ++, в сборочном модуле (файл .asm), а вторая работает примерно на 20% быстрее!

Однако накладные расходы вызов функции является значительным: если я сравниваю вторую реализацию сборки "is_power_of_two_fast" со встроенной версией функции шаблона, последняя работает быстрее, несмотря на ветки!

К сожалению, новые соглашения для x64 указывают, что встроенная сборка не выполняется позволил. Вместо этого следует использовать «внутренние функции».

Теперь вопрос: могу ли я реализовать более быструю версию "is_power_of_two_fast" как собственную встроенную функцию или что-то подобное, чтобы ее можно было использовать встроенно? Или, альтернативно, Можно ли каким-то образом заставить компилятор создать версию функции с младшими ветвями?

7
задан Deduplicator 18 February 2015 в 15:47
поделиться