equivalente provável/improvável para MSVC
-
10-07-2019 - |
Pergunta
O compilador GCC suporta a instrução __builtin_expect que é usada para definir macros prováveis e improváveis.
por exemplo.
#define likely(expr) (__builtin_expect(!!(expr), 1))
#define unlikely(expr) (__builtin_expect(!!(expr), 0))
Existe uma instrução equivalente para o compilador Microsoft Visual C ou algo equivalente?
Solução
eu digo apenas punt
Não há nada igual.Há __presumir(), mas não a use, é um tipo diferente de diretiva de otimizador.
Na verdade, a razão pela qual o gnu embutido está agrupado em uma macro é para que você possa se livrar dele automaticamente se __GNUC__
não está definido.Não há nada de necessário nessas macros e aposto que você não notará a diferença no tempo de execução.
Resumo
Apenas se livre de (anular) *likely
em não-GNU.Você não vai perder.
Outras dicas
De acordo com http://www.akkadia.org/drepper/cpumemory.pdf (página 57), ainda faz sentido usar a previsão de ramificação estática, mesmo que a CPU preveja corretamente de forma dinâmica.A razão para isso é que o cache L1i será usado de forma ainda mais eficiente se a previsão estática for feita corretamente.
O padrão C++20 incluirá [[likely]]
e [[unlikely]]
atributos de previsão de ramificação.
A última revisão da proposta de atributos pode ser encontrada em http://wg21.link/p0479
A proposta original do atributo pode ser encontrada em http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0479r0.html
Os programadores devem preferir o PGO.Os atributos podem facilmente reduzir o desempenho se aplicados incorretamente ou se tornarem incorretos posteriormente quando o programa for alterado.
__presumir deveria ser semelhante.
No entanto, se você quiser fazer isso muito bem, você deve usar Otimização guiada por perfil em vez de dicas estáticas.
De acordo com Reorganização de ramificações e loops para evitar previsões erradas documento da Intel:
Para escrever seu código efetivamente para aproveitar essas regras, ao escrever instruções de if-else ou alternar, verifique os casos mais comuns primeiro e trabalhe progressivamente até o menos comum.
Infelizmente você não pode escrever algo como
#define if_unlikely(cond) if (!(cond)); else
porque o otimizador MSVC a partir do VS10 ignora essa "dica".
Como prefiro lidar primeiro com os erros no meu código, pareço escrever um código menos eficiente.Felizmente, na segunda vez que a CPU encontrar o branch, ela usará suas estatísticas em vez de uma dica estática.