Vc ahora está en modo de mantenimiento y ya no se desarrolla activamente. Sin embargo, continuamos revisando las solicitudes de extracción con correcciones de errores de la comunidad.
Quizás le interese cambiar a std-simd. GCC 11 incluye una versión experimental de std::simd
como parte de libstdc++, que también funciona con clang. Las funciones presentes en Vc 1.4 y no presentes en std-simd eventualmente se convertirán en Vc 2.0, que luego dependerá de std-simd .
Las generaciones recientes de CPU, y de GPU en particular, requieren códigos de datos paralelos para lograr una eficiencia total. El paralelismo de datos requiere que se aplique la misma secuencia de operaciones a diferentes datos de entrada. Por lo tanto, las CPU y GPU pueden reducir el hardware necesario para la decodificación y programación de instrucciones en favor de más unidades aritméticas y lógicas, que ejecutan las mismas instrucciones de forma sincrónica. En las arquitecturas de CPU, esto se implementa mediante registros e instrucciones SIMD. Un solo registro SIMD puede almacenar N valores y una sola instrucción SIMD puede ejecutar N operaciones en esos valores. En las arquitecturas de GPU, N subprocesos se ejecutan en perfecta sincronización, alimentados por un único decodificador/programador de instrucciones. Cada hilo tiene memoria local y un índice determinado para calcular las compensaciones en la memoria para cargas y tiendas.
Los compiladores de C++ actuales pueden realizar transformaciones automáticas de códigos escalares a instrucciones SIMD (autovectorización). Sin embargo, el compilador debe reconstruir una propiedad intrínseca del algoritmo que se perdió cuando el desarrollador escribió una implementación puramente escalar en C++. En consecuencia, los compiladores de C++ no pueden vectorizar ningún código determinado a su variante de datos paralelos más eficiente. Los bucles de datos paralelos especialmente grandes, que abarcan múltiples funciones o incluso unidades de traducción, a menudo no se transformarán en código SIMD eficiente.
La biblioteca Vc proporciona el eslabón perdido. Sus tipos permiten establecer explícitamente operaciones de datos paralelos en múltiples valores. Por tanto, el paralelismo se añade mediante el sistema de tipos. Los enfoques opuestos establecen el paralelismo a través de nuevas estructuras de control y, en consecuencia, nueva semántica dentro del cuerpo de estas estructuras de control.
Vc es una biblioteca de software gratuita para facilitar la vectorización explícita del código C++. Tiene una API intuitiva y proporciona portabilidad entre diferentes compiladores y versiones de compilador, así como portabilidad entre diferentes conjuntos de instrucciones vectoriales. Por tanto, se puede compilar una aplicación escrita con Vc para:
Después de que Intel dejó de admitir MIC con ICC 18, Vc 1.4 también eliminó la compatibilidad con él.
std::vector<Particle>
simdize
d en muchos std::vector<float>
. Tenga en cuenta lo importante que es la bandera -march
, en comparación con -mavx2 -mfma
simple.Comencemos con el código para calcular un producto escalar 3D usando flotadores 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 vectorizar fácilmente el código usando el 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 ];
}
Lo anterior se escalará a 1, 4, 8, 16, etc. productos escalares calculados en paralelo, según las capacidades del hardware de destino.
A modo de comparación, la misma vectorización que utiliza los intrínsecos de Intel SSE es más detallada y utiliza notación de prefijo (es decir, llamadas a funciones):
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 ]));
}
Lo anterior no se escalará a AVX, AVX-512, etc. ni es portátil a otros SIMD ISA.
cmake >= 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 un directorio de instalación:
$ cmake -DCMAKE_INSTALL_PREFIX=/opt/Vc ..
Opcionalmente, incluya la creación de pruebas unitarias:
$ cmake -DBUILD_TESTING=ON ..
En Windows, si tiene varias versiones de Visual Studio instaladas, puede seleccionar una:
$ cmake -G " Visual Studio 16 2019 " ..
Consulte cmake --help
para obtener una lista de posibles generadores.
$ cmake --build . -j 16
$ cmake --install . # may require permissions
En Windows, también puede abrir Vc.sln
en Visual Studio y compilarlo/instalarlo desde el IDE.
La documentación se genera a través de doxygen. Puede crear la documentación ejecutando doxygen
en el subdirectorio doc
. Alternativamente, puede encontrar versiones nocturnas de la documentación en:
Trabajar en la integración de la funcionalidad de Vc en la biblioteca estándar de C++.
Vc se publica bajo los términos de la licencia BSD de 3 cláusulas.