According to this page https://sourceware.org/glibc/wiki/libmvec, I should be able to manually vectorize a few complicated instructions like cosine by using the libmvec functions. However, I don't know how to get gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0 to recognize them. Am I missing some compiler flags or something? Any help or suggestions are appreciated.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <immintrin.h>
// gcc libmvectest.c -o libmvectest.bin -lm -O3 -Wall -ffast-math -march=msse4
int main(int argc, char **argv)
{
float input = 0.1;
float res[4];
__m128 m128 = _mm_set1_ps(input);
__m128 cosm128 = _ZGVbN4ua16vl_cosf(m128);
_mm_storeu_ps(res, cosm128);
printf("%.8f %.8f\n", cosf(input), res[0]);
}
I've googled the 'implicit declaration...' error for the prefixed functions but failed to find an answer that worked for me. I tried _ZGVbN4ua16vl_cos, _ZGVbN4ua16vl_cosf and other attempts. Does anyone know where the actual function names are listed?
Thanks to all who looked into this. The main point of the question was to manually vectorize using those built in functions so as to not rely on the optimiser which can easily get confused if you're doing more than just a simple one function loop. The suggestion by Peter Cordes worked on my system so this code now compiles and runs successfully.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <immintrin.h>
// gcc libmvectest.c -o libmvectest.bin -lm -O3 -Wall -ffast-math -march=msse4
extern __m128 _ZGVbN4v_cosf(__m128);
int main(int argc, char **argv)
{
float input = 0.1;
float res[4];
__m128 m128 = _mm_set1_ps(input);
__m128 cosm128 = _ZGVbN4v_cosf(m128);
_mm_storeu_ps(res, cosm128);
printf("%.8f %.8f\n", cosf(input), res[0]);
}
Those OpenMP-SIMD clones are not intended to be invoked by hand from portable C. They are not declared as separate functions; instead, they are introduced as multiple variants of a standard function via #pragma omp declare simd
or __attribute__((simd))
for use by automatic vectorization. On a Glibc-based system you can inspect the declarations in /usr/include/bits/math-vector.h
.
For use in explicitly vectorized code you can write simple wrappers with a trivially vectorizable loop like this:
#include <immintrin.h>
__attribute__((simd("notinbranch")))
float cosf(float);
__m128 t(__m128 x)
{
for (int i = 0; i < sizeof x / sizeof x[0]; i++)
x[i] = cosf(x[i]);
return x;
}
which gcc -O2 -ftree-vectorize
is able to optimize to
t:
jmp _ZGVbN4v_cosf
https://godbolt.org/z/jdfeoT7K5
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With