Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #130450
| From | "F. Russell" <fr@random.info> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | OpenMP and AVX2 Problem |
| Date | 2018-05-12 15:09 +0000 |
| Organization | NewsGuy.com |
| Message-ID | <pd703u02761@news2.newsguy.com> (permalink) |
I am using AVX2 intrinsics to speed up math calculations.
For example, using AVX2 can speed up the vector cross product,
C = A X B, by a factor of 4, which for large arrays of vectors
is a huge boost to performance.
I am now thinking of using openmp to create multi-threaded
routines where each processor, or thread, can execute the
same AVX2 instructions on a part of the array. This should
speed thing up by at least another factor of four.
However, my initial attempts do not work. In fact, using
openmp slows the calculations down by a factor of 5.
I must be doing something wrong but I don't know what.
Before I hit the references for some deep research on openmp
I thought I would first post my code example here.
The code is quite simple. There is just a for loop
over an array of vectors using AVX2 intrinsics. The
sample code is posted at the end.
Since AVX2 operates on 4 double FP values, the array
is an array of struct with each struct containing 4
double components. The fourth component is not used
but needs to be there because the values must be 32-byte
aligned.
Using an array of size N=1,000,000 here are my results:
Run Time Single-Thread: 0.010427 seconds
Run Time Multi-Thread: 0.05072 seconds
The following code was compiled with gcc using the command:
gcc -O0 -march=native -fopenmp -o vectprod-parallel vectprod-parallel.c
I used "-O0" so that the compiler would not optimize the code
and only the multi-threading would make any diference.
==================
C code begin
==================
// vector cross product with avx2 intrinsics
// C = A X B
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <x86intrin.h>
#include <time.h>
#include <omp.h>
typedef struct {
double vx;
double vy;
double vz;
double vw;
} vector4;
int main()
{
int i, N=1e6;
double *res, seconds;
clock_t start, end;
vector4 *vectA, *vectB, *vectC;
__m256d a, b, c;
// allocate arrays of vector4 with 32-byte alignment
vectA = (vector4 *)memalign(32, N*sizeof(vector4));
vectB = (vector4 *)memalign(32, N*sizeof(vector4));
vectC = (vector4 *)memalign(32, N*sizeof(vector4));
// initialize arrays with test values
for(i=0; i<N; i++) {
(vectA+i)->vx=1.0; vectA[i].vy=2.0; (vectA+i)->vz=3.0;
(vectB+i)->vx=6.0; vectB[i].vy=4.0; (vectB+i)->vz=5.0;
}
start = clock();
// calculate with AVX2 over the array
for(i=0; i<N; i++ ) {
a = _mm256_load_pd((double *)(vectA+i));
b = _mm256_load_pd((double *)(vectB+i));
c = _mm256_permute4x64_pd
(
_mm256_sub_pd
(
_mm256_mul_pd(a, _mm256_permute4x64_pd(b, _MM_SHUFFLE(3, 0, 2, 1))),
_mm256_mul_pd(b, _mm256_permute4x64_pd(a, _MM_SHUFFLE(3, 0, 2, 1)))
),
_MM_SHUFFLE(3, 0, 2, 1)
);
_mm256_store_pd((double *)(vectC+i), c);
}
end = clock();
seconds = (double)(end - start)/CLOCKS_PER_SEC;
printf("\n\nRun Time Single-Thread: %g seconds\n\n", seconds);
// Print test result of last vector: -2, 13, -8
res=(double *)(vectC+(N-1));
fprintf(stdout, "%g %g %g %g\n", res[0], res[1], res[2], res[3]);
// multi-threaded AVX2 vector product loop
start = clock();
// set up parallel loop with openmp
#pragma omp parallel for private(i, a, b, c) shared(vectA, vectB, vectC)
for(i=0; i<N; i++) {
a = _mm256_load_pd((double *)(vectA+i));
b = _mm256_load_pd((double *)(vectB+i));
c = _mm256_permute4x64_pd
(
_mm256_sub_pd
(
_mm256_mul_pd(a, _mm256_permute4x64_pd(b, _MM_SHUFFLE(3, 0, 2, 1))),
_mm256_mul_pd(b, _mm256_permute4x64_pd(a, _MM_SHUFFLE(3, 0, 2, 1)))
),
_MM_SHUFFLE(3, 0, 2, 1)
);
_mm256_store_pd((double *)(vectC+i), c);
}
end = clock();
seconds = (double)(end - start)/CLOCKS_PER_SEC;
printf("\n\nRun Time Multi-Thread: %g seconds\n\n", seconds);
// Print test result of last vector: -2, 13, -8
res=(double *)(vectC+(N-1));
fprintf(stdout, "%g %g %g %g\n", res[0], res[1], res[2], res[3]);
free(vectA); free(vectB); free(vectC);
return(0);
}
=======================
End C code
=======================
Back to comp.lang.c | Previous | Next — Next in thread | Find similar | Unroll thread
OpenMP and AVX2 Problem "F. Russell" <fr@random.info> - 2018-05-12 15:09 +0000
Re: OpenMP and AVX2 Problem Tim Prince <tprince@intelretiree.com> - 2018-05-12 11:33 -0400
Re: OpenMP and AVX2 Problem Melzzzzz <Melzzzzz@zzzzz.com> - 2018-05-12 16:05 +0000
Re: OpenMP and AVX2 Problem "F. Russell" <fr@random.info> - 2018-05-12 17:46 +0000
Re: OpenMP and AVX2 Problem "F. Russell" <fr@random.info> - 2018-05-12 19:10 +0000
Re: OpenMP and AVX2 Problem [SOLVED] "F. Russell" <fr@random.info> - 2018-05-12 19:42 +0000
Re: OpenMP and AVX2 Problem [SOLVED] Keith Thompson <kst-u@mib.org> - 2018-05-12 14:04 -0700
Re: OpenMP and AVX2 Problem scott@slp53.sl.home (Scott Lurndal) - 2018-05-13 17:47 +0000
Re: OpenMP and AVX2 Problem Wouter Verhelst <w@uter.be> - 2018-05-13 09:57 +0200
csiph-web