Vc está agora em modo de manutenção e não está mais em desenvolvimento ativo. No entanto, continuamos analisando pull requests com correções de bugs da comunidade.
Você pode estar interessado em mudar para std-simd. O GCC 11 inclui uma versão experimental de std::simd
como parte do libstdc++, que também funciona com clang. Os recursos presentes no Vc 1.4 e não presentes no std-simd eventualmente se transformarão no Vc 2.0, que então depende do std-simd .
As gerações recentes de CPUs, e GPUs em particular, exigem códigos paralelos de dados para eficiência total. O paralelismo de dados requer que a mesma sequência de operações seja aplicada a diferentes dados de entrada. CPUs e GPUs podem, assim, reduzir o hardware necessário para decodificação e escalonamento de instruções em favor de mais unidades aritméticas e lógicas, que executam as mesmas instruções de forma síncrona. Nas arquiteturas de CPU, isso é implementado por meio de registros e instruções SIMD. Um único registrador SIMD pode armazenar N valores e uma única instrução SIMD pode executar N operações sobre esses valores. Nas arquiteturas de GPU, N threads são executados em perfeita sincronia, alimentados por um único decodificador/escalonador de instruções. Cada thread possui memória local e um determinado índice para calcular os deslocamentos na memória para cargas e armazenamentos.
Os compiladores C++ atuais podem fazer transformação automática de códigos escalares em instruções SIMD (vetorização automática). Entretanto, o compilador deve reconstruir uma propriedade intrínseca do algoritmo que foi perdida quando o desenvolvedor escreveu uma implementação puramente escalar em C++. Conseqüentemente, os compiladores C++ não podem vetorizar qualquer código para sua variante paralela de dados mais eficiente. Loops paralelos de dados especialmente maiores, abrangendo múltiplas funções ou mesmo unidades de tradução, muitas vezes não serão transformados em código SIMD eficiente.
A biblioteca Vc fornece o elo perdido. Seus tipos permitem declarar explicitamente operações paralelas de dados em vários valores. O paralelismo é, portanto, adicionado através do sistema de tipos. Abordagens concorrentes afirmam o paralelismo através de novas estruturas de controle e, consequentemente, de novas semânticas dentro do corpo dessas estruturas de controle.
Vc é uma biblioteca de software livre para facilitar a vetorização explícita de código C++. Possui uma API intuitiva e fornece portabilidade entre diferentes compiladores e versões de compiladores, bem como portabilidade entre diferentes conjuntos de instruções vetoriais. Assim, uma aplicação escrita com Vc pode ser compilada para:
Depois que a Intel abandonou o suporte MIC com ICC 18, o Vc 1.4 também removeu o suporte para ele.
std::vector<Particle>
simdize
em muitos std::vector<float>
. Observe o quão importante é o sinalizador -march
, comparado ao simples -mavx2 -mfma
.Vamos começar com o código para calcular um produto escalar 3D usando flutuadores integrados:
using Vec3D = std::array< float , 3 >;
float scalar_product (Vec3D a, Vec3D b) {
return a[ 0 ] * b[ 0 ] + a[ 1 ] * b[ 1 ] + a[ 2 ] * b[ 2 ];
}
Usando Vc, podemos vetorizar facilmente o código usando o tipo float_v
:
using Vc::float_v
using Vec3D = std::array<float_v, 3 >;
float_v scalar_product (Vec3D a, Vec3D b) {
return a[ 0 ] * b[ 0 ] + a[ 1 ] * b[ 1 ] + a[ 2 ] * b[ 2 ];
}
O acima será dimensionado para 1, 4, 8, 16, etc. produtos escalares calculados em paralelo, dependendo das capacidades do hardware alvo.
Para efeito de comparação, a mesma vetorização usando intrínsecos Intel SSE é mais detalhada e usa notação de prefixo (ou seja, chamadas de função):
using Vec3D = std::array<__m128, 3 >;
__m128 scalar_product (Vec3D a, Vec3D b) {
return _mm_add_ps ( _mm_add_ps ( _mm_mul_ps (a[ 0 ], b[ 0 ]), _mm_mul_ps (a[ 1 ], b[ 1 ])),
_mm_mul_ps (a[ 2 ], b[ 2 ]));
}
O acima não será dimensionado para AVX, AVX-512, etc. nem será portátil para outros ISAs SIMD.
cmmake >= 3,0
Compilador C++ 11:
git clone https://github.com/VcDevel/Vc.git
cd Vc
git submodule update --init
$ mkdir build
$ cd build
$ cmake ..
Opcionalmente, especifique um diretório de instalação:
$ cmake -DCMAKE_INSTALL_PREFIX=/opt/Vc ..
Opcionalmente, inclua a construção dos testes unitários:
$ cmake -DBUILD_TESTING=ON ..
No Windows, se você tiver várias versões do Visual Studio instaladas, poderá selecionar uma:
$ cmake -G " Visual Studio 16 2019 " ..
Veja cmake --help
para uma lista de possíveis geradores.
$ cmake --build . -j 16
$ cmake --install . # may require permissions
No Windows, você também pode abrir Vc.sln
no Visual Studio e compilar/instalar a partir do IDE.
A documentação é gerada via doxygen. Você pode construir a documentação executando doxygen
no subdiretório doc
. Alternativamente, você pode encontrar compilações noturnas da documentação em:
Trabalhe na integração da funcionalidade do Vc na biblioteca padrão C++.
Vc é lançado sob os termos da licença BSD de 3 cláusulas.