Quais arquivos de cabeçalho fornecem as intrínsecas para as diferentes extensões do conjunto de instruções x86 SIMD (MMX, SSE, AVX, ...)? Parece impossível encontrar essa lista online. Corrija-me se eu estiver errado.
fonte
Quais arquivos de cabeçalho fornecem as intrínsecas para as diferentes extensões do conjunto de instruções x86 SIMD (MMX, SSE, AVX, ...)? Parece impossível encontrar essa lista online. Corrija-me se eu estiver errado.
Hoje em dia você normalmente deve apenas incluir <immintrin.h>
. Inclui tudo.
O GCC e o clang impedirão você de usar intrínsecos para instruções que você não ativou no momento da compilação (por exemplo, com -march=native
ou -mavx2 -mbmi2 -mpopcnt -mfma -mcx16 -mtune=znver1
ou o que for.)
O MSVC e o ICC permitem usar intrínsecos sem ativar nada no tempo de compilação, mas você ainda deve habilitar o AVX antes de usar os intrínsecos do AVX.
Historicamente (antes de obter immintrin.h
tudo), era necessário incluir manualmente um cabeçalho para o mais alto nível de intrínsecas que você desejava.
Isso ainda pode ser útil com o MSVC e o ICC para impedir o uso de conjuntos de instruções que você não deseja exigir.
<mmintrin.h> MMX
<xmmintrin.h> SSE
<emmintrin.h> SSE2
<pmmintrin.h> SSE3
<tmmintrin.h> SSSE3
<smmintrin.h> SSE4.1
<nmmintrin.h> SSE4.2
<ammintrin.h> SSE4A
<wmmintrin.h> AES
<immintrin.h> AVX, AVX2, FMA
Incluindo um desses puxões em todos os anteriores (exceto o SSE4A somente AMD: immintrin.h
não puxa isso)
Alguns compiladores também têm <zmmintrin.h>
para o AVX512.
#include <x86intrin.h>
que extrai tudo o que você precisa.<zmmintrin.h>
diretamente; O GCC nem o fornece. Basta usar<immintrin.h>
ou o ainda mais completo<x86intrin.h>
. Essa resposta é basicamente obsoleta, a menos que você intencionalmente evite incluir intrínsecos para versões mais recentes do SSE, porque seu compilador não reclama quando você usa uma instrução SSE4.1 durante a compilação do SSE2. (gcc / clang que reclamar, então você deve apenas usar immintrin.h para eles IDK sobre os outros..)No GCC / clang, se você usar apenas
incluirá todos os cabeçalhos SSE / AVX que são ativados de acordo com as opções do compilador, como
-march=haswell
apenas-march=native
. Além disso, algumas instruções específicas do x86, comobswap
ouror
se tornam disponíveis como intrínsecas.O equivalente MSVC deste cabeçalho
<intrin.h>
Se você quiser apenas o SIMD portátil, use
#include <immintrin.h>
MSVC, ICC e gcc / clang (e outros compiladores como a Sun, eu acho) suportam esse cabeçalho para as intrínsecas SIMD documentadas pela única ferramenta de busca / pesquisa intrínseca da Intel: https://software.intel.com/sites/landingpage/IntrinsicsGuide /
fonte
<x86intrin.h>
, mas<intrin.h>
alcança um efeito semelhante. Você ainda precisa de compilação condicional, é claro. :-(#include <immintrin.h>
. Use isso para intrínsecas do SIMD. Você só precisa do tamanho ainda maior (e um pouco mais lento para o compilador)x86intrin.h
ouintrin.h
se precisar de itens como intrínsecos de rotação / varredura de bits inteiros (embora a Intel documente alguns deles como disponíveis noimmintrin.h
guia de intrínsecos ).x86intrin.h
/intrin.h
mas não emimmintrin.h
.O nome do cabeçalho depende do seu compilador e arquitetura de destino.
intrin.h
x86intrin.h
arm_neon.h
mmintrin.h
altivec.h
spe.h
Você pode lidar com todos esses casos com diretivas de pré-processamento condicional:
fonte
A partir desta página
Portanto, em geral, você pode incluir apenas
immintrin.h
para obter todas as extensões Intel, oux86intrin.h
se quiser tudo, incluindo_bit_scan_forward
e_rdtsc
, além de todas as intrínsecas de vetores, incluindo apenas AMD. Se você for contra, incluindo mais do que realmente precisa, poderá escolher a inclusão correta olhando para a mesa.x86intrin.h
é a maneira recomendada de obter intrínsecas para o AMD XOP (somente Bulldozer, nem mesmo os futuros processadores AMD) , em vez de ter seu próprio cabeçalho.Alguns compiladores ainda gerarão mensagens de erro se você usar elementos intrínsecos para conjuntos de instruções que você não ativou (por exemplo,
_mm_fmadd_ps
sem ativar o fma, mesmo se você incluirimmintrin.h
e ativar o AVX2).fonte
smmintrin
(SSE4.1) é Penryn (45 nm Core2), não Nehalem ("i7"). Podemos parar de usar "i7" como um nome de arquitetura? Não faz sentido agora que a Intel continuou usando-o para a família SnB .immintrin.h
parece não incluir_popcnt32
e_popcnt64
(não deve ser confundido com os que estão dentropopcntintrin.h
!) intrínsecas no GCC 9.1.0. Então parece quex86intrin.h
ainda serve a um propósito.Como muitas das respostas e comentários declararam,
<x86intrin.h>
é o cabeçalho abrangente para intrínsecas do SIMD x86 [-64]. Ele também fornece instruções de suporte intrínsecas para outras extensões ISA.gcc
,,clang
eicc
todos decidiram isso. Eu precisava pesquisar algumas versões que suportam o cabeçalho e pensei que poderia ser útil listar algumas descobertas ...gcc : o suporte para o
x86intrin.h
primeiro aparece emgcc-4.5.0
. Agcc-4
série de lançamentos não está mais sendo mantida, enquantogcc-6.x
a atual é a série estável.gcc-5
também introduziu a__has_include
extensão presente em todas asclang-3.x
versões.gcc-7
está em pré-lançamento (teste de regressão, etc.) e segue o esquema de versão atual, será lançado comogcc-7.1.0
.clang :
x86intrin.h
parece ter sido suportado para todos osclang-3.x
lançamentos. A última versão estável éclang (LLVM) 3.9.1
. O ramo de desenvolvimento éclang (LLVM) 5.0.0
. Não está claro o que aconteceu com a4.x
série.Clang da Apple : irritantemente, o versionamento da Apple não corresponde ao dos
LLVM
projetos. Dito isto, a versão atual:,clang-800.0.42.1
é baseada emLLVM 3.9.0
. A primeiraLLVM 3.0
versão baseada parece estar deApple clang 2.1
voltaXcode 4.1
.LLVM 3.1
aparece pela primeira vez comApple clang 3.1
(uma coincidência numérica) emXcode 4.3.3
.A Apple também define
__apple_build_version__
, por exemplo8000042
,. Esse parece ser o esquema de versão mais estável e estritamente ascendente disponível. Se você não deseja oferecer suporte a compiladores herdados, torne um desses valores um requisito mínimo.Qualquer versão recente
clang
, incluindo as versões da Apple, não deve ter nenhum problemax86intrin.h
. Obviamente, junto comgcc-5
, você sempre pode usar o seguinte:Um truque em que você realmente não pode confiar é usar as
__GNUC__
versõesclang
. O controle de versão é, por razões históricas, bloqueado4.2.1
. Uma versão que precede ox86intrin.h
cabeçalho. Ocasionalmente, é útil para, digamos, extensões GNU C simples que permaneceram compatíveis com versões anteriores.icc : pelo que sei, o
x86intrin.h
cabeçalho é suportado desde pelo menos Intel C ++ 16.0. O teste versão pode por executada com:#if (__INTEL_COMPILER >= 1600)
. Esta versão (e possivelmente versões anteriores) também fornece suporte para a__has_include
extensão.MSVC : Parece que
MSVC++ 12.0 (Visual Studio 2013)
é a primeira versão a fornecer ointrin.h
cabeçalho - nãox86intrin.h
... isso sugere:#if (_MSC_VER >= 1800)
como um teste de versão. Obviamente, se você estiver tentando escrever um código portátil em todos esses diferentes compiladores, o nome do cabeçalho nessa plataforma será o menor dos seus problemas.fonte