Invólucros de C ++ para Intrinsics SIMD
SIMD (instrução única, vários dados) é um recurso dos microprocessadores que estão disponíveis há muitos anos. As instruções SIMD executam uma única operação em um lote de valores de uma só vez e, portanto, fornecem uma maneira de acelerar significativamente a execução do código. No entanto, essas instruções diferem entre os fornecedores e compiladores do microprocessador.
xsimd fornece um meio unificado para usar esses recursos para autores de bibliotecas. Ou seja, permite a manipulação de lotes de números com os mesmos operadores aritméticos que para valores únicos. Ele também fornece implementação acelerada de funções matemáticas comuns que operam em lotes.
Além do XTensor, o XSIMD foi adotado por principais projetos de código aberto, como Mozilla Firefox, Apache Arrow, Pythran e Krita.
O projeto XSIMD começou com uma série de artigos de blog de Johan Mabille sobre como implementar invólucros para o Simd Intrinsicts. Os arquivos do blog podem ser encontrados aqui: o cientista do C ++. O design descrito nos artigos permaneceu próximo da arquitetura real do XSIMD até a versão 8.0.
As funções matemáticas são uma implementação leve dos algoritmos implementados originalmente no projeto agora prejudicado.
xsimd requer um compilador compilador de C ++ 11. Os seguintes compiladores C ++ são suportados:
| Compilador | Versão |
|---|---|
| Microsoft Visual Studio | Atualização 2 do MSVC 2015 e acima |
| g ++ | 4.9 e acima |
| Clang | 4.0 e acima |
As seguintes extensões do conjunto de instruções SIMD são suportadas:
| Arquitetura | Extensões do conjunto de instruções |
|---|---|
| x86 | SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, FMA3+SSE, FMA3+AVX, FMA3+AVX2 |
| x86 | AVX512BW, AVX512CD, AVX512DQ, AVX512F (GCC7 e Superior) |
| x86 AMD | FMA4 |
| BRAÇO | Neon, neon64, SVE128/256/512 (tamanho fixo do vetor) |
| WebAssembly | WASM |
| Risc-v | RISC-V128/256/512 (tamanho fixo do vetor) |
Um pacote para o XSIMD está disponível no gerenciador de pacotes Mamba (ou CONDA).
mamba install -c conda-forge xsimdUm pacote para XSIMD está disponível no gerenciador de pacotes SPACH.
spack install xsimd
spack load xsimdVocê pode instalá -lo diretamente a partir das fontes com cmake:
cmake -D CMAKE_INSTALL_PREFIX=your_install_prefix .
make install Para começar usando xsimd , confira a documentação completa
http://xsimd.readthedocs.io/
xsimd tem uma dependência opcional da biblioteca XTL:
xsimd | xtl (opcional) |
|---|---|
| mestre | ^0,7.0 |
| 12.x | ^0,7.0 |
| 11.x | ^0,7.0 |
| 10.x | ^0,7.0 |
| 9.x | ^0,7.0 |
| 8.x | ^0,7.0 |
A dependência do xtl é necessária se você deseja suportar a vetorização para xtl::xcomplex . Nesse caso, você deve criar seu projeto com o suporte C ++ 14 ativado.
A versão 8 da biblioteca é uma reescrita completa e há algumas pequenas diferenças com as versões 7.x. Um guia de migração estará disponível em breve. Enquanto isso, os exemplos a seguir mostram como usar as versões 7 e 8 da biblioteca?
Aqui está um exemplo que calcula a média de dois conjuntos de 4 valores de ponto flutuante duplo, assumindo que a extensão AVX seja suportada:
# include < iostream >
# include " xsimd/xsimd.hpp "
namespace xs = xsimd;
int main ( int argc, char * argv[])
{
xs::batch< double , xs::avx2> a = { 1.5 , 2.5 , 3.5 , 4.5 };
xs::batch< double , xs::avx2> b = { 2.5 , 3.5 , 4.5 , 5.5 };
auto mean = (a + b) / 2 ;
std::cout << mean << std::endl;
return 0 ;
} Não se esqueça de ativar a extensão do AVX ao criar o exemplo. Com o GCC ou CLANG, isso é feito com o sinalizador -mavx , no MSVC, você precisa passar a opção /arch:AVX .
Este exemplo sai:
( 2.0 , 3.0 , 4.0 , 5.0 )A mesma computação operando em vetores e usando o maior conjunto de instruções de desempenho disponível:
# include < cstddef >
# include < vector >
# include " xsimd/xsimd.hpp "
namespace xs = xsimd;
using vector_type = std::vector< double , xsimd::aligned_allocator< double >>;
void mean ( const vector_type& a, const vector_type& b, vector_type& res)
{
std:: size_t size = a. size ();
constexpr std:: size_t simd_size = xsimd::simd_type< double >::size;
std:: size_t vec_size = size - size % simd_size;
for (std:: size_t i = 0 ; i < vec_size; i += simd_size)
{
auto ba = xs::load_aligned (&a[i]);
auto bb = xs::load_aligned (&b[i]);
auto bres = (ba + bb) / 2 .;
bres. store_aligned (&res[i]);
}
for (std:: size_t i = vec_size; i < size; ++i)
{
res[i] = (a[i] + b[i]) / 2 .;
}
}Construir os testes requer cmake.
cmake está disponível como um pacote para a maioria das distribuições Linux. Além disso, eles também podem ser instalados com o gerenciador de pacotes conda (mesmo no Windows):
conda install -c conda-forge cmake Depois que cmake é instalado, você pode construir e executar os testes:
mkdir build
cd build
cmake ../ -DBUILD_TESTS=ON
make xtest No contexto de integração contínua com Travis CI, os testes são executados em um ambiente conda , que pode ser ativado com
cd test
conda env create -f ./test-environment.yml
source activate test-xsimd
cd ..
cmake . -DBUILD_TESTS=ON
make xtestA documentação do XSIMD é construída com três ferramentas
Enquanto o doxygen deve ser instalado separadamente, você pode instalar o Breathe digitando
pip install breathe Respira também pode ser instalado com conda
conda install -c conda-forge breatheFinalmente, construa a documentação com
make html do subdiretório docs .
Utilizamos um modelo de direitos autorais compartilhado que permite que todos os colaboradores mantenham os direitos autorais de suas contribuições.
Este software está licenciado sob a licença BSD-3-cláusula. Consulte o arquivo de licença para obter detalhes.