Rust vectorization: a second look

submited by
Style Pass
2021-05-16 08:45:18

Research is characterized by allowing yourself to make mistakes: performing experiments; drawing conclusions; later, realizing that your experiment was not sufficient and you got it wrong; and trying again. Back in March, we thought that we knew how to deal with vectorized Rust: tell the compiler not to auto-vectorize code; tell the compiler not to use vector instructions; and use existing conditional compilation feature flags to disable hand-vectorized code. Unfortunately, two of those three ideas don’t work – but we think we have a viable approach now.

The first of these ideas probably works: you can tell the compiler not to auto-vectorize code. If you are using cargo, you can control this with RUSTFLAGS; if you are using rustc directly, you can directly disable auto-vectorization when invoking rustc. And, if your program calls C code (or uses a crate that calls C code) and uses the CC-rs crate to compile the code, then you can easily pass flags to the C compiler to disable auto-vectorization. (If your program calls C code that was not compiled using the CC-rs crate, you will need to modify the C code’s build system – which is a bit more work.)

The reason that telling the compiler not to use vector instructions does not work is that it is not possible to turn off the x86 architecture’s SSE2 instructions without breaking floating point. We recently realized that the -Ctarget-feature=-sse2 flag turns of both SSE2 vector instructions and also support for IEEE floating point. With IEEE floating point disabled, LLVM attempts to use the old 80-bit x87 floating point unit and then fails an assertion while compiling your code. In short, you cannot use the -sse2 flag with Rust. It took us a while to recognize that we could not just disable SSE2 because, the technique we were using to disable SSE2 in the standard library turned out to do nothing. We thought that we could do this using the environment variable RUSTFLAGS_STAGE_NOT_0 to disable SSE2 (and other x86 vector extensions) when compiling the standard library. Alas, this environment variable has been renamed so our attempt to disable SSE2 was being ignored.

Leave a Comment