- Notifications
You must be signed in to change notification settings - Fork151
SIMD Vector Classes for C++
License
VcDevel/Vc
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Vc is now in maintenance mode and no longer actively developed.However, we continue to review pull requests with bugfixes from the community.
You may be interested in switching tostd-simd.GCC 11 includes an experimental version ofstd::simd
as part of libstdc++, which also works with clang.Features present in Vc 1.4 and not present instd-simd will eventually turn into Vc 2.0,which then depends onstd-simd.
Recent generations of CPUs, and GPUs in particular, require data-parallel codesfor full efficiency. Data parallelism requires that the same sequence ofoperations is applied to different input data. CPUs and GPUs can thus reducethe necessary hardware for instruction decoding and scheduling in favor of morearithmetic and logic units, which execute the same instructions synchronously.On CPU architectures this is implemented via SIMD registers and instructions.A single SIMD register can store N values and a single SIMD instruction canexecute N operations on those values. On GPU architectures N threads run inperfect sync, fed by a single instruction decoder/scheduler. Each thread haslocal memory and a given index to calculate the offsets in memory for loads andstores.
Current C++ compilers can do automatic transformation of scalar codes to SIMDinstructions (auto-vectorization). However, the compiler must reconstruct anintrinsic property of the algorithm that was lost when the developer wrote apurely scalar implementation in C++. Consequently, C++ compilers cannotvectorize any given code to its most efficient data-parallel variant.Especially larger data-parallel loops, spanning over multiple functions or eventranslation units, will often not be transformed into efficient SIMD code.
The Vc library provides the missing link. Its types enable explicitly statingdata-parallel operations on multiple values. The parallelism is therefore addedvia the type system. Competing approaches state the parallelism via new controlstructures and consequently new semantics inside the body of these controlstructures.
Vc is a free software library to ease explicit vectorization of C++ code. Ithas an intuitive API and provides portability between different compilers andcompiler versions as well as portability between different vector instructionsets. Thus an application written with Vc can be compiled for:
- AVX and AVX2
- SSE2 up to SSE4.2 or SSE4a
- Scalar
AVX-512 (Vc 2 development)NEON (in development)NVIDIA GPUs / CUDA (research)
After Intel dropped MIC support with ICC 18, Vc 1.4 also removed support for it.
- Simdize Example
- Total momentum and time stepping of
std::vector<Particle>
- Matrix Example: This uses verticalvectorization which does not scale to different vector sizes. However, theexample is instructive to compare it with similar solutions of other languagesor libraries.
- N-vortex solver showing
simdize
d iterationover manystd::vector<float>
. Note howimportant the-march
flag is, comparedto plain-mavx2 -mfma
.
Let's start from the code for calculating a 3D scalar product using builtin floats:
using Vec3D = std::array<float,3>;floatscalar_product(Vec3D a, Vec3D b) {return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];}
Using Vc, we can easily vectorize the code using thefloat_v
type:
using Vc::float_vusing Vec3D = std::array<float_v,3>;float_vscalar_product(Vec3D a, Vec3D b) {return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];}
The above will scale to 1, 4, 8, 16, etc. scalar products calculated in parallel, dependingon the target hardware's capabilities.
For comparison, the same vectorization using Intel SSE intrinsics is more verbose and usesprefix notation (i.e. function calls):
using Vec3D = std::array<__m128,3>;__m128scalar_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]));}
The above will neither scale to AVX, AVX-512, etc. nor is it portable to other SIMD ISAs.
cmake >= 3.0
C++11 Compiler:
- GCC >= 4.8.1
- clang >= 3.4
- ICC >= 18.0.5
- Visual Studio 2019 (64-bit target)
- Clone Vc and initialize Vc's git submodules:
git clone https://github.com/VcDevel/Vc.gitcd Vcgit submodule update --init
- Create a build directory:
$ mkdir build$cd build
- Configure with cmake and add relevant options:
$ cmake ..
Optionally, specify an installation directory:
$ cmake -DCMAKE_INSTALL_PREFIX=/opt/Vc ..
Optionally, include building the unit tests:
$ cmake -DBUILD_TESTING=ON ..
On Windows, if you have multiple versions of Visual Studio installed, you can select one:
$ cmake -G"Visual Studio 16 2019" ..
Seecmake --help
for a list of possible generators.
- Build and install:
$ cmake --build. -j 16$ cmake --install.# may require permissions
On Windows, you can also openVc.sln
in Visual Studio and build/install from the IDE.
The documentation is generated viadoxygen. You can buildthe documentation by runningdoxygen
in thedoc
subdirectory.Alternatively, you can find nightly builds of the documentation at:
- 1.4 branch
- 1.4.4 release
- 1.4.3 release
- 1.4.2 release
- 1.4.1 release
- 1.4.0 release
- 1.3 branch
- 1.3.0 release
- 1.2.0 release
- 1.1.0 release
- 0.7 branch
- M. Kretz, "Extending C++ for Explicit Data-Parallel Programming via SIMDVector Types", Goethe University Frankfurt, Dissertation,2015.
- M. Kretz and V. Lindenstruth, "Vc: A C++ library for explicitvectorization", Software: Practice and Experience,2011.
- M. Kretz, "Efficient Use of Multi- and Many-Core Systems with Vectorizationand Multithreading", University of Heidelberg,2009.
Work on integrating the functionality of Vc in the C++ standard library.
Vc is released under the terms of the3-clause BSD license.
About
SIMD Vector Classes for C++