On Thursday, 30 September 2021 at 16:52:57 UTC, Johan wrote:
On Thursday, 30 September 2021 at 16:40:03 UTC, james.p.leblanc

Generally, for performance issues like this you need to study assembly output (`--output-s`) or LLVM IR (`--output-ll`).
First thing I would look out for is function inlining yes/no.

cheers,
  Johan

Johan,

Thanks kindly for your reply. As suggested, I have looked at the assembly output.

Strangely the fused multiplay add are indeed there in the avx version, but example
still runs slower for **Complex!float** data type.

I have stripped the code down to a minimum, which demonstrates the weird result:



```d

import ldc.attributes; // with or without this line makes no difference
import std.stdio;
import std.datetime.stopwatch;
import std.complex;

alias T = Complex!float;
auto typestr = "COMPLEX FLOAT";
/* alias T = Complex!double; */
/* auto typestr = "COMPLEX DOUBLE"; */

auto alpha = cast(T) complex(0.1, -0.2); // dummy values to fill arrays
auto beta = cast(T) complex(-0.7, 0.6);

auto dotprod( T[] x, T[] y)
{
   auto sum = cast(T) 0;
      foreach( size_t i ; 0 .. x.length)
         sum += x[i] * conj(y[i]);
   return sum;
}

void main()
{
   int nEle = 1000;
   int nIter = 2000;

   auto startTime = MonoTime.currTime;
auto dur = cast(double) (MonoTime.currTime-startTime).total!"usecs";

   T[] x, y;
   x.length = nEle;
   y.length = nEle;
   T z;
   x[] = alpha;
   y[] = beta;

   startTime = MonoTime.currTime;
   foreach( i ; 0 .. nIter){
      foreach( j ; 0 .. nIter){
            z = dotprod(x,y);
      }
   }
auto etime = cast(double) (MonoTime.currTime-startTime).total!"msecs" / 1.0e3; writef(" result: % 5.2f%+5.2fi comp time: %5.2f \n", z.re, z.im, etime);
}
```

For convenience I include bash script used compile/run/generate assembly code / and grep:

```bash
echo
echo "With AVX:"
ldc2 -O3 -release question.d --ffast-math -mcpu=haswell
question
ldc2 -output-s -O3 -release question.d --ffast-math -mcpu=haswell
mv question.s question_with_avx.s

echo
echo "Without AVX"
ldc2 -O3 -release question.d
question
ldc2 -output-s -O3 -release question.d
mv question.s question_without_avx.s

echo
echo "fused multiply adds are found in avx code (as desired)"
grep vfmadd *.s /dev/null
```

Here is output when run on my machine:

```console
With AVX:
 result:  -190.00+80.00i  comp time:   6.45

Without AVX
 result:  -190.00+80.00i  comp time:   5.74

fused multiply adds are found in avx code (as desired)
question_with_avx.s:    vfmadd231ss     %xmm2, %xmm5, %xmm3
question_with_avx.s:    vfmadd231ss     %xmm0, %xmm2, %xmm3
question_with_avx.s:    vfmadd231ss     %xmm2, %xmm4, %xmm1
question_with_avx.s:    vfmadd231ss     %xmm3, %xmm5, %xmm1
question_with_avx.s:    vfmadd231ss     %xmm3, %xmm1, %xmm0

```

Repeating the experiment after changing to datatype of Complex!double shows AVX code to be twice as fast (perhaps more aligned with expectations).

**I admit my confusion as to why the Complex!float is misbehaving.**

Does anyone have insight to what is happening?

Thanks,
James


Reply via email to