Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #130451

Re: OpenMP and AVX2 Problem

From Tim Prince <tprince@intelretiree.com>
Newsgroups comp.lang.c
Subject Re: OpenMP and AVX2 Problem
Date 2018-05-12 11:33 -0400
Message-ID <flog8iFpme6U1@mid.individual.net> (permalink)
References <pd703u02761@news2.newsguy.com>

Show all headers | View raw


On 5/12/2018 11:09 AM, F. Russell wrote:
> 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
> =======================
> 
You are measuring total time summed up from all threads. The usual
expectation is for threading parallelism to reduce elapsed time at the
expense of using more threads.  If you are using 4 threads and pin them
all to different cores, and you have 99% L1 cache hit rate, you would
hope to reduce elapsed time, but you might still be increasing your
total time of all threads by a factor of 3. If you use 2 cores, hoping
that hyperthreads will give you a gain of more than 2x, you are likely
to be disappointed.  I know, it took me several months to confirm that
my laptop is dual core hyperthreaded, as there seemed to be an attempt
to mislead, in part by preventing the disabling of hyperthreads.

-- 
Tim Prince

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


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