Vc 1.4 for explicit SIMD data parallelism in C++
SIMD Vector Classes for C++
At a glance
- What is it?
- Vc supplies C++ vector types that express operations over multiple values without introducing compiler-specific intrinsics. It targets AVX, AVX2, SSE, and scalar builds, but it is now in maintenance mode and omits several targets once listed for later development.
- Who is it for?
- Vc is appropriate for an existing C++11 codebase that needs explicit SIMD across supported x86 instruction sets and can accept a maintenance-mode dependency. It is a poor fit for a new design that requires AVX-512, NEON, CUDA, or a growing feature set.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 108 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The vectorization gap Vc targets in C++
Vc addresses C++ code that performs the same operation across multiple independent values but leaves that parallelism implicit. Compilers can auto-vectorize scalar programs, according to the project documentation, but the compiler has to recover information that was not represented in the source. Larger data-parallel loops are especially difficult when work crosses function or translation-unit boundaries. As a result, an available SIMD instruction set does not guarantee that the compiler will choose the most efficient vector form.
The intended users are C++ developers who know that their workload is data-parallel and want control over that structure without writing Intel SSE intrinsics directly. Typical examples in the repository cover particle calculations, matrices, finite differences, search, and iterative scientific computations. Vc is not a general-purpose task scheduler or an automatic vectorizer. Its defining choice is to put data parallelism into the types themselves, so ordinary expressions can operate on several values at once.
This distinction matters for decision-making. Auto-vectorization can be attractive when scalar code is clear and the compiler handles the required loop shape. Vc is more relevant when the developer needs portable vector expressions, operates on fixed-size groups, or cannot rely on the compiler to preserve and propagate vectorization opportunities.
How Vc maps C++ expressions to SIMD types
Vc introduces vector types such as `Vc::float_v`. Its scalar-product example changes `Vec3D` from `std::array<float, 3>` to `std::array<float_v, 3>`, then keeps the multiplication and addition expressions intact. Each expression now represents parallel operations over the values held by `float_v`. The number of scalar products evaluated together depends on the selected target hardware, rather than being fixed by handwritten instructions in the application.
The API is expression-oriented. In contrast to the SSE version shown by the README, which calls `_mm_mul_ps`, `_mm_add_ps`, and related intrinsics, Vc overloads familiar C++ operators. That lets an application describe the computation without selecting an AVX, AVX2, or SSE intrinsic sequence in each function. The library documentation claims portability across compilers, compiler versions, and supported vector instruction sets.
That portability has boundaries. Vc 1.4 documents AVX, AVX2, SSE2 through SSE4.2 or SSE4a, and scalar builds. AVX-512, NEON, and NVIDIA GPU or CUDA support appear in struck-through development notes rather than as supported Vc 1.4 targets. MIC support was removed after Intel ended it with ICC 18. Consequently, “portable” here principally means portability among the listed CPU instruction sets, not portability across every processor architecture.
Building Vc 1.4 from the default branch
The repository documents a source build with CMake 3.0 or later and a C++11 compiler. Start by cloning the project and initializing its submodules. The subdirectory does not exist yet, so this step is not optional:
git clone https://github.com/VcDevel/Vc.git
cd Vc
git submodule update --initThe reader should now be in the repository root. Create and enter a build directory before running CMake:
$ mkdir build
$ cd buildThe basic configuration invokes CMake against the parent directory:
$ cmake ..To choose the installation location, pass `CMAKE_INSTALL_PREFIX`. The README gives `/opt/Vc` as an example:
$ cmake -DCMAKE_INSTALL_PREFIX=/opt/Vc ..Unit tests are optional and are enabled through `BUILD_TESTING`:
$ cmake -DBUILD_TESTING=ON ..Build and installation are separate steps. The `-j 16` value is the example parallelism level from the README, not a project requirement:
$ cmake --build . -j 16
$ cmake --install . # may require permissionsOn a system with several Visual Studio installations, the documented generator selection is:
$ cmake -G "Visual Studio 16 2019" ..The README also says that `Vc.sln` can be opened and built in Visual Studio. It does not give a short `find_package` example for consuming the installed library from another CMake project, so that integration step must be verified separately.
A first explicit vectorization with float_v
The clearest first use is Vc's scalar-product transformation. Begin with three ordinary `float` values and calculate their dot product. The README's baseline uses `std::array<float, 3>` and indexes each component explicitly:
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];
}After configuring the application to include Vc through the project mechanism used by your build, replace the component type with `Vc::float_v`. The documented implementation is:
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];
}The significant change is not a new loop or intrinsic function. `float_v` makes each arithmetic operation data-parallel while preserving the expression structure. The documentation states that the compiled result can calculate multiple scalar products according to the target hardware's capabilities. The example includes three `float_v` components, so the dimensions are application-defined. It does not promise that a three-element vector maps perfectly to every hardware register width.
For a real application, compile the final configuration rather than assuming that enabling isolated instruction flags is enough. The README's N-vortex discussion specifically warns that the `-march` flag matters, and links a comparison with `-mavx2 -mfma`. Compiler Explorer examples can therefore help inspect code generation, but deployment should use the same target settings as the shipped build.
Maintenance state, compiler coverage, and upgrade choices
The README places Vc in maintenance mode and says it is no longer actively developed. Community pull requests containing bug fixes are still reviewed. The repository is not archived, and its last push was on 2026-07-07, but neither fact changes the project's explicit maintenance designation. The latest listed release is Vc 1.4.5 from 2024-06-06, following 1.4.4 from 2023-10-06 and 1.4.3 from 2022-05-20.
Vc 1.4 requires CMake 3.0 or later. Its documented C++11 compiler floor is GCC 4.8.1, clang 3.4, ICC 18.0.5, or Visual Studio 2019 with a 64-bit target. These are minimums stated by the project, not evidence that every later compiler and warning configuration remains compatible. A team adopting Vc should test its actual compiler matrix because bug-fix review is the stated development policy.
The repository is licensed under BSD-3-Clause. That permits use and modification under the license's conditions, but this review does not interpret those conditions as legal advice. Vendoring, notices, and compatibility with an organization's policy remain project-specific checks.
The main alternative named by the README is `std-simd`. Its approach is based on standard-style vector types, with an experimental `std::simd` available in GCC 11's libstdc++ and usable with clang according to the README. Vc 1.4 and `std-simd` do not currently have identical feature coverage. The project says missing Vc 1.4 features may eventually move into a future Vc 2.0 that depends on `std-simd`. That is a roadmap statement, not a delivered Vc 2.0 release.
Where Vc 1.4 is the wrong tool
The clearest wrong-tool case is a project that needs a target excluded from Vc 1.4. AVX-512, NEON, and CUDA are not available supported targets in the documented feature list, so choosing Vc for those requirements would misstate its portability. Scalar code that a current compiler already vectorizes cleanly is also a reasonable reason to keep the implementation simpler.
Explicit vector types also impose design choices. Fixed-width expressions can be useful for regular data, but they are not a drop-in answer to every irregular loop. The README's matrix example describes vertical vectorization as instructive while warning that it does not scale to different vector sizes. That illustrates a real design constraint: changing the vector width can alter the decomposition of the algorithm, not merely the number of values processed per instruction.
Vc 1.4 is also a weak choice when future feature growth is a primary requirement. The maintenance notice, restricted target set, and experimental `std-simd` migration direction increase long-term integration questions. Existing applications may still gain value from its established operator-based API, especially where portability across the documented x86 instruction sets matters. New applications should first establish whether the available compiler vectorization is sufficient and whether `std-simd` covers their actual requirements.
Editorial conclusion
Vc is appropriate for an existing C++11 codebase that needs explicit SIMD across supported x86 instruction sets and can accept a maintenance-mode dependency. It is a poor fit for a new design that requires AVX-512, NEON, CUDA, or a growing feature set. Before adoption, verify the target instruction sets in your deployment environment, confirm that your CMake and compiler versions remain within the documented requirements, and test the exact `-march` configuration used by your build because the README identifies it as important.
Frequently asked questions
What is Vc used for in C++?
Vc provides explicit, portable vector types for data-parallel C++ operations. The README presents it as an alternative to relying entirely on compiler auto-vectorization or writing instruction-set-specific intrinsics.
How do I build and install Vc 1.4?
Clone the repository, initialize its submodules, create a build directory, run CMake, then use `cmake --build .` and `cmake --install .`. The documented prerequisites are CMake 3.0 or later and a supported C++11 compiler.
Is Vc still actively developed, and what is the alternative?
The README says Vc is in maintenance mode and no longer actively developed, although community bug-fix pull requests are reviewed. It points users toward `std-simd`, while noting that not every Vc 1.4 feature is present there yet.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vcdevel-vc)Was this useful?