This forum has been archived. All content is frozen. Please use KDE Discuss instead.

partialPivLu performance

Tags: None
(comma "," separated)
jcm
Registered Member
Posts
5
Karma
0

partialPivLu performance

Tue Apr 26, 2016 3:42 pm
Hi Eigen users,

I need to get the solution x to the equation Ax=b.
A is square and invertible, so I'm using `partialPivLu`. In our software, the typical sizes for N is in between 1000 and 6000.
The time Eigen takes to solve this problem is too long for our use case. Therefore, I tried alternative solvers (LAPACK from Accelerate framework of MacOSX and MKL). Surprisingly, it showed that they run approx. 2.5-3x faster than Eigen's `partialPivLu`.

I use Eigen 3.2.8 on MacOSX/Xcode 7.3. I did a cross check on windows using VisualStudio 2013 and get similar results. I've set the appropriate environment variables to run all the cases in single threaded mode (the time difference in multi-threaded mode is even bigger).

I'm wondering if it's expected that Eigen's `partialPivLu` is much slower. This seems to confirm it (although it's with beta 3.3):
http://www.mathematik.uni-ulm.de/~lehn/ ... age01.html
but the official Eigen benchmark page gives a different result:
http://download.tuxfamily.org/eigen/btl ... decomp.pdf

I've tried to run Eigen's benchmarks (on MacOSX), but compilation failed on `use of undeclared identifier 'CLOCK_*`.
What can I try to get better performance out of Eigen's solver? (I'd like to avoid MKL If possible)

Below my simple benchmark code that gives following result:

partialPivLu, N=5: 0.017786 ms
dgesv, N=5: 0.029173 ms
partialPivLu, N=20: 0.018849 ms
dgesv, N=20: 0.007163 ms
partialPivLu, N=100: 0.180609 ms
dgesv, N=100: 0.113047 ms
partialPivLu, N=200: 0.953346 ms
dgesv, N=200: 0.405534 ms
partialPivLu, N=500: 11.4266 ms
dgesv, N=500: 4.00285 ms
partialPivLu, N=750: 32.81 ms
dgesv, N=750: 12.9065 ms
partialPivLu, N=1000: 72.307 ms
dgesv, N=1000: 25.8653 ms
partialPivLu, N=2000: 502.714 ms
dgesv, N=2000: 186.132 ms
partialPivLu, N=3000: 1688.85 ms
dgesv, N=3000: 573.236 ms
partialPivLu, N=6000: 11961.9 ms
dgesv, N=6000: 4125.76 ms


Code: Select all
#include "PartialPivLuSolver.h"
#include <Accelerate/Accelerate.h>
#include <Eigen/Dense>
#include <chrono>
#include <iostream>
#include <vector>

using namespace Eigen;
using namespace std::chrono;

void runPartialPivLuSolverBenchmarks()
{
    // Get the solution x to the equation Ax=b
    // A is square and invertible.
    // Using partial pivoting LU decomposition.
   
    // This code uses the `Accelerate` from MacOSX as LAPACK implementation.
    // By default, it runs multi-threaded.
    // To force single-threaded mode, add environment variable `VECLIB_MAXIMUM_THREADS=1`.
   
    std::vector<int> Narray = {5, 20, 100, 200, 500, 750, 1000, 2000, 3000, 6000};
    for (int N : Narray)
    {

        MatrixXd A = MatrixXd::Random(N, N);
        VectorXd b = VectorXd::Random(N);
       
        // Vector for results
        VectorXd xEigen, xLapack;

        {
            auto start = high_resolution_clock::now();
            xEigen = A.partialPivLu().solve(b);
            auto dur = high_resolution_clock::now() - start;
            std::cout << "partialPivLu, N=" << N << ": " << duration_cast<nanoseconds>(dur).count() / 1000000.0 << "ms" << std::endl;
        }
       
        // Lapack (this test needs to be last, because it modifies A)
        {
            auto start = high_resolution_clock::now();
            xLapack = b;
            int N = A.rows();
            int NRHS = b.cols();
            Eigen::VectorXi ipiv(A.rows());
            int info;
            dgesv_(&N, &NRHS, A.data(), &N, ipiv.data(), xLapack.data(), &N, &info);
            if (info != 0) {
                throw std::runtime_error("FHAnalysis::solve: dgesv failed");
            }
            auto dur = high_resolution_clock::now() - start;
            std::cout << "dgesv, N=" << N << ": " << duration_cast<nanoseconds>(dur).count() / 1000000.0 << "ms" << std::endl;
        }

       
        // Compare results
        constexpr double tol = 1e-6;

        for (VectorXd::Index i=0, sz=xEigen.size(); i<sz; ++i) {
            if (std::abs(xEigen[i] - xLapack[i]) > tol) {
                throw std::runtime_error("mismatching results");
            }
        }
    }
}


Thanks for your help.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: partialPivLu performance

Thu Apr 28, 2016 9:28 pm
Here for n=6000 it takes 4.7s on my macbook 2.6GHz, compiled with "g++ -mfma -O3" on OSX and using Eigen 3.3. You need it to exploit AVX and FMA, otherwise it takes 12s (as expected: AVX -> x2, FMA -> x1.5).
jcm
Registered Member
Posts
5
Karma
0

Re: partialPivLu performance

Tue May 03, 2016 11:49 am
ggael wrote:Here for n=6000 it takes 4.7s on my macbook 2.6GHz, compiled with "g++ -mfma -O3" on OSX and using Eigen 3.3. You need it to exploit AVX and FMA, otherwise it takes 12s (as expected: AVX -> x2, FMA -> x1.5).


Thanks. Great to see the improvments in 3.3 to close the gap.

I could observe similar improvments when using the default clang compiler of Xcode 7.3 (with 3.3 beta 1 and using -mfma flag).

With VisuaStudio however, the results were less spectacular. I tried with both VisualStudio 2013 and VisualStudio 2015. In all the combinations I tried, the runtime for n=6000 drops from 12s to 8.5s when using the '/arch:AVX2' flag. I tried with 3.3 beta1 and todays 'default' branch in the repository.

According to https://blogs.msdn.microsoft.com/vcblog/2014/02/28/avx2-support-in-visual-studio-c-compiler/, the '/arch:AVX2' flag should enable fma.

Is there any other flag I missed?
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: partialPivLu performance

Tue May 03, 2016 8:47 pm
the only way to investigate this is too look at the generated assembly of the function Eigen::internal::gebp_kernel. Maybe it is messing with register allocation.
jcm
Registered Member
Posts
5
Karma
0

Re: partialPivLu performance

Wed May 04, 2016 8:09 am
ggael wrote:the only way to investigate this is too look at the generated assembly of the function Eigen::internal::gebp_kernel. Maybe it is messing with register allocation.

I actually saw no fma instructions in the assembly. I couldn't find a separate FMA flag in MSVC, but the page linked above suggested that '/arch:AVX2' would enable fma. However I noticed that the '__FMA__' macro was not defined. It seems that MSVC defines '__AVX2__', but not '__FMA__' (https://msdn.microsoft.com/en-us/library/b0084kay.aspx).

I then tried to add a '#define __FMA__' before including eigen and the runtime improved by 1.5s (7s, vs 8.5s without __FMA__ macro). This is still quite a lot worse than what gcc or clang produces.

I'm not used to read assembly. I can't judge if MSVC is messing with register allocation. Below is the assembly (with the '#define __FMA__' hack). Please let me know if I can help otherwise.

Code: Select all
template<typename LhsScalar, typename RhsScalar, typename Index, typename DataMapper, int mr, int nr, bool ConjugateLhs, bool ConjugateRhs>
EIGEN_DONT_INLINE
void gebp_kernel<LhsScalar,RhsScalar,Index,DataMapper,mr,nr,ConjugateLhs,ConjugateRhs>
  ::operator()(const DataMapper& res, const LhsScalar* blockA, const RhsScalar* blockB,
               Index rows, Index depth, Index cols, ResScalar alpha,
               Index strideA, Index strideB, Index offsetA, Index offsetB)
  {
00007FF6F87D4C80  mov         rax,rsp 
00007FF6F87D4C83  mov         qword ptr [rax+8],rbx 
00007FF6F87D4C87  mov         qword ptr [rax+20h],r9 
00007FF6F87D4C8B  mov         qword ptr [rax+18h],r8 
00007FF6F87D4C8F  push        rbp 
00007FF6F87D4C90  push        rsi 
00007FF6F87D4C91  push        rdi 
00007FF6F87D4C92  push        r12 
00007FF6F87D4C94  push        r13 
00007FF6F87D4C96  push        r14 
00007FF6F87D4C98  push        r15 
00007FF6F87D4C9A  sub         rsp,320h 
00007FF6F87D4CA1  vmovaps     xmmword ptr [rax-48h],xmm6 
00007FF6F87D4CA6  vmovaps     xmmword ptr [rax-58h],xmm7 
00007FF6F87D4CAB  vmovaps     xmmword ptr [rax-68h],xmm8 
00007FF6F87D4CB0  vmovaps     xmmword ptr [rax-78h],xmm9 
00007FF6F87D4CB5  vmovaps     xmmword ptr [rax-88h],xmm10 
00007FF6F87D4CBD  vmovaps     xmmword ptr [rax-98h],xmm11 
00007FF6F87D4CC5  vmovaps     xmmword ptr [rax-0A8h],xmm12 
00007FF6F87D4CCD  vmovaps     xmmword ptr [rax-0B8h],xmm13 
00007FF6F87D4CD5  vmovaps     xmmword ptr [rax-0C8h],xmm14 
00007FF6F87D4CDD  vmovaps     xmmword ptr [rax-0D8h],xmm15 
00007FF6F87D4CE5  lea         rbp,[rsp+20h] 
00007FF6F87D4CEA  and         rbp,0FFFFFFFFFFFFFFE0h 
    Traits traits;
    SwappedTraits straits;
   
    if(strideA==-1) strideA = depth;
00007FF6F87D4CEE  mov         rsi,qword ptr [depth] 
00007FF6F87D4CF6  mov         r14,rdx 
    if(strideB==-1) strideB = depth;
    conj_helper<LhsScalar,RhsScalar,ConjugateLhs,ConjugateRhs> cj;
    Index packet_cols4 = nr>=4 ? (cols/4) * 4 : 0;
    const Index peeled_mc3 = mr>=3*Traits::LhsProgress ? (rows/(3*LhsProgress))*(3*LhsProgress) : 0;
00007FF6F87D4CF9  mov         rcx,qword ptr [rows] 
00007FF6F87D4D01  mov         r13,r9 
00007FF6F87D4D04  mov         r11,qword ptr [strideA] 
00007FF6F87D4D0C  mov         r10,r8 
00007FF6F87D4D0F  mov         r15,qword ptr [strideB] 
00007FF6F87D4D17  cmp         r11,0FFFFFFFFFFFFFFFFh 
00007FF6F87D4D1B  mov         rax,qword ptr [cols] 
    const Index peeled_mc2 = mr>=2*Traits::LhsProgress ? peeled_mc3+((rows-peeled_mc3)/(2*LhsProgress))*(2*LhsProgress) : 0;
    const Index peeled_mc1 = mr>=1*Traits::LhsProgress ? (rows/(1*LhsProgress))*(1*LhsProgress) : 0;
    enum { pk = 8 }; // NOTE Such a large peeling factor is important for large matrices (~ +5% when >1000 on Haswell)
    const Index peeled_kc  = depth & ~(pk-1);
00007FF6F87D4D23  mov         r8,rsi 
00007FF6F87D4D26  cmove       r11,rsi 
    const Index prefetch_res_offset = 32/sizeof(ResScalar);   
//     const Index depth2     = depth & ~1;

    //---------- Process 3 * LhsProgress rows at once ----------
    // This corresponds to 3*LhsProgress x nr register blocks.
    // Usually, make sense only with FMA
    if(mr>=3*Traits::LhsProgress)
    {     
      PossiblyRotatingKernelHelper<gebp_kernel> possiblyRotatingKernelHelper(traits);
     
      // Here, the general idea is to loop on each largest micro horizontal panel of the lhs (3*Traits::LhsProgress x depth)
      // and on each largest micro vertical panel of the rhs (depth * nr).
      // Blocking sizes, i.e., 'depth' has been computed so that the micro horizontal panel of the lhs fit in L1.
      // However, if depth is too small, we can extend the number of rows of these horizontal panels.
      // This actual number of rows is computed as follow:
      const Index l1 = defaultL1CacheSize; // in Bytes, TODO, l1 should be passed to this function.
      // The max(1, ...) here is needed because we may be using blocking params larger than what our known l1 cache size
      // suggests we should be using: either because our known l1 cache size is inaccurate (e.g. on Android, we can only guess),
      // or because we are testing specific blocking sizes.
      const Index actual_panel_rows = (3*LhsProgress) * std::max<Index>(1,( (l1 - sizeof(ResScalar)*mr*nr - depth*nr*sizeof(RhsScalar)) / (depth * sizeof(LhsScalar) * 3*LhsProgress) ));
00007FF6F87D4D2A  mov         qword ptr [rbp+1E0h],1 
      for(Index i1=0; i1<peeled_mc3; i1+=actual_panel_rows)
00007FF6F87D4D35  vmovsd      xmm2,qword ptr [alpha] 
00007FF6F87D4D3E  cqo 
00007FF6F87D4D40  mov         qword ptr [rbp+8],r11 
00007FF6F87D4D44  cmp         r15,0FFFFFFFFFFFFFFFFh 
00007FF6F87D4D48  vmovsd      qword ptr [rbp+20h],xmm2 
00007FF6F87D4D4D  cmove       r15,rsi 
00007FF6F87D4D51  and         edx,3 
00007FF6F87D4D54  and         r8,0FFFFFFFFFFFFFFF8h 
00007FF6F87D4D58  mov         qword ptr [rbp+28h],r15 
00007FF6F87D4D5C  lea         rbx,[rdx+rax] 
00007FF6F87D4D60  mov         rax,2AAAAAAAAAAAAAABh 
00007FF6F87D4D6A  imul        rcx 
00007FF6F87D4D6D  and         rbx,0FFFFFFFFFFFFFFFCh 
00007FF6F87D4D71  sar         rdx,1 
00007FF6F87D4D74  mov         rax,rdx 
00007FF6F87D4D77  mov         qword ptr [rbp+30h],rbx 
00007FF6F87D4D7B  shr         rax,3Fh 
00007FF6F87D4D7F  add         rdx,rax 
00007FF6F87D4D82  mov         rax,rcx 
00007FF6F87D4D85  lea         r9,[rdx+rdx*2] 
00007FF6F87D4D89  shl         r9,2 
00007FF6F87D4D8D  sub         rax,r9 
00007FF6F87D4D90  mov         qword ptr [rbp],r9 
00007FF6F87D4D94  cqo 
00007FF6F87D4D96  mov         qword ptr [peeled_mc3],r9 
00007FF6F87D4D9D  and         edx,7 
00007FF6F87D4DA0  add         rax,rdx 
00007FF6F87D4DA3  sar         rax,3 
00007FF6F87D4DA7  lea         r12,[r9+rax*8] 
00007FF6F87D4DAB  mov         rax,rcx 
00007FF6F87D4DAE  cqo 
00007FF6F87D4DB0  mov         qword ptr [peeled_mc2],r12 
00007FF6F87D4DB4  and         edx,3 
00007FF6F87D4DB7  lea         rcx,[rsi+rsi*2] 
00007FF6F87D4DBB  add         rax,rdx 
00007FF6F87D4DBE  shl         rcx,5 
00007FF6F87D4DC2  and         rax,0FFFFFFFFFFFFFFFCh 
00007FF6F87D4DC6  xor         edx,edx 
00007FF6F87D4DC8  mov         qword ptr [rbp+48h],rax 
00007FF6F87D4DCC  imul        rax,rsi,0FFFFFFFFFFFFFFE0h 
00007FF6F87D4DD0  add         rax,7E80h 
00007FF6F87D4DD6  mov         qword ptr [rbp+40h],rax 
00007FF6F87D4DDA  div         rax,rcx 
00007FF6F87D4DDD  mov         rdx,qword ptr [offsetB] 
    const Index prefetch_res_offset = 32/sizeof(ResScalar);   
//     const Index depth2     = depth & ~1;

    //---------- Process 3 * LhsProgress rows at once ----------
    // This corresponds to 3*LhsProgress x nr register blocks.
    // Usually, make sense only with FMA
    if(mr>=3*Traits::LhsProgress)
    {     
      PossiblyRotatingKernelHelper<gebp_kernel> possiblyRotatingKernelHelper(traits);
     
      // Here, the general idea is to loop on each largest micro horizontal panel of the lhs (3*Traits::LhsProgress x depth)
      // and on each largest micro vertical panel of the rhs (depth * nr).
      // Blocking sizes, i.e., 'depth' has been computed so that the micro horizontal panel of the lhs fit in L1.
      // However, if depth is too small, we can extend the number of rows of these horizontal panels.
      // This actual number of rows is computed as follow:
      const Index l1 = defaultL1CacheSize; // in Bytes, TODO, l1 should be passed to this function.
      // The max(1, ...) here is needed because we may be using blocking params larger than what our known l1 cache size
      // suggests we should be using: either because our known l1 cache size is inaccurate (e.g. on Android, we can only guess),
      // or because we are testing specific blocking sizes.
      const Index actual_panel_rows = (3*LhsProgress) * std::max<Index>(1,( (l1 - sizeof(ResScalar)*mr*nr - depth*nr*sizeof(RhsScalar)) / (depth * sizeof(LhsScalar) * 3*LhsProgress) ));
00007FF6F87D4DE5  mov         ecx,1 
00007FF6F87D4DEA  cmp         rax,rcx 
00007FF6F87D4DED  mov         qword ptr [rbp+1D8h],rax 
00007FF6F87D4DF4  cmovg       rcx,rax 
00007FF6F87D4DF8  lea         rax,[rcx+rcx*2] 
      for(Index i1=0; i1<peeled_mc3; i1+=actual_panel_rows)
00007FF6F87D4DFC  xor         ecx,ecx 
00007FF6F87D4DFE  shl         rax,2 
00007FF6F87D4E02  mov         qword ptr [rbp+70h],rax 
00007FF6F87D4E06  mov         qword ptr [rbp+10h],rcx 
00007FF6F87D4E0A  test        r9,r9 
00007FF6F87D4E0D  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0E40h (07FF6F87D5AC0h) 
      {
        const Index actual_panel_end = (std::min)(i1+actual_panel_rows, peeled_mc3);
00007FF6F87D4E13  add         rax,rcx 
00007FF6F87D4E16  cmp         r9,rax 
00007FF6F87D4E19  mov         qword ptr [rbp+68h],rax 
00007FF6F87D4E1D  mov         r12,rax 
00007FF6F87D4E20  mov         qword ptr [rbp+1E8h],rax 
00007FF6F87D4E27  cmovl       r12,r9 
00007FF6F87D4E2B  mov         qword ptr [actual_panel_end],r12 
        for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D4E2F  test        rbx,rbx 
00007FF6F87D4E32  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0B7Dh (07FF6F87D57FDh) 
      {
        const Index actual_panel_end = (std::min)(i1+actual_panel_rows, peeled_mc3);
00007FF6F87D4E38  xor         eax,eax 
00007FF6F87D4E3A  lea         rdx,[r15*4] 
00007FF6F87D4E42  mov         qword ptr [rbp],rax 
00007FF6F87D4E46  mov         qword ptr [rbp+60h],rdx 
00007FF6F87D4E4A  lea         r13d,[rax+2] 
00007FF6F87D4E4E  xchg        ax,ax 
        {
          for(Index i=i1; i<actual_panel_end; i+=3*LhsProgress)
00007FF6F87D4E50  mov         r15,rcx 
00007FF6F87D4E53  cmp         rcx,r12 
00007FF6F87D4E56  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0B46h (07FF6F87D57C6h) 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D4E5C  mov         r9,qword ptr [offsetB] 
00007FF6F87D4E64  lea         rdx,[r13-1] 
00007FF6F87D4E68  vxorps      ymm0,ymm0,ymm0 
00007FF6F87D4E6C  vmovupd     ymm1,ymm0 
00007FF6F87D4E70  vmovaps     xmm0,xmm2 
00007FF6F87D4E74  lea         rax,[rax+r9*4] 
00007FF6F87D4E78  mov         r9,qword ptr [blockB] 
00007FF6F87D4E80  vbroadcastsd ymm7,xmm0 
00007FF6F87D4E85  vmovupd     ymmword ptr [rbp+200h],ymm1 
          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
00007FF6F87D4E8D  lea         rdi,[r13+1] 
00007FF6F87D4E91  lea         rax,[r9+rax*8] 
00007FF6F87D4E95  mov         qword ptr [rbp+18h],rax 
00007FF6F87D4E99  lea         rax,[r11+r11*2] 
00007FF6F87D4E9D  shl         rax,5 
00007FF6F87D4EA1  mov         qword ptr [rbp+58h],rax 
00007FF6F87D4EA5  mov         rax,rcx 
00007FF6F87D4EA8  imul        rax,r11 
          }

#undef EIGEN_GEBP_ONESTEP

          possiblyRotatingKernelHelper.unrotateResult(C0, C1, C2, C3);
          possiblyRotatingKernelHelper.unrotateResult(C4, C5, C6, C7);
          possiblyRotatingKernelHelper.unrotateResult(C8, C9, C10, C11);

          ResPacket R0, R1, R2;
          ResPacket alphav = pset1<ResPacket>(alpha);
00007FF6F87D4EAC  vmovupd     ymmword ptr [alphav],ymm7 
00007FF6F87D4EB4  lea         r12,[r10+rax*8] 
00007FF6F87D4EB8  nop         dword ptr [rax+rax] 
          {
         
          // We selected a 3*Traits::LhsProgress x nr micro block of res which is entirely
          // stored into 3 x nr registers.
         
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(3*LhsProgress)];
00007FF6F87D4EC0  mov         r9,r12 
          prefetch(&blA[0]);
00007FF6F87D4EC3  prefetcht0  [r12] 

          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
00007FF6F87D4EC8  mov         rax,qword ptr [r14+8] 
00007FF6F87D4ECC  lea         r10,[r13-2] 
00007FF6F87D4ED0  mov         rcx,qword ptr [r14] 
          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
00007FF6F87D4ED3  mov         rbx,rax 
00007FF6F87D4ED6  imul        rbx,r13 

          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
00007FF6F87D4EDA  imul        r10,rax 
          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
00007FF6F87D4EDE  imul        rdi,rax 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D4EE2  mov         r11,rdx 
          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
00007FF6F87D4EE5  add         rbx,r15 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D4EE8  imul        r11,rax 

          // gets res block as register
          AccPacket C0, C1, C2,  C3,
                    C4, C5, C6,  C7,
                    C8, C9, C10, C11;
          traits.initAcc(C0);  traits.initAcc(C1);  traits.initAcc(C2);  traits.initAcc(C3);
00007FF6F87D4EEC  vmovupd     ymm9,ymm1 
          traits.initAcc(C4);  traits.initAcc(C5);  traits.initAcc(C6);  traits.initAcc(C7);
00007FF6F87D4EF0  vmovupd     ymm15,ymm1 
          traits.initAcc(C8);  traits.initAcc(C9);  traits.initAcc(C10); traits.initAcc(C11);
00007FF6F87D4EF4  vmovupd     ymm2,ymm1 
00007FF6F87D4EF8  vmovupd     ymm6,ymm1 

          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
00007FF6F87D4EFC  add         r10,r15 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D4EFF  add         r11,r15 
          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
00007FF6F87D4F02  add         rdi,r15 

          // gets res block as register
          AccPacket C0, C1, C2,  C3,
                    C4, C5, C6,  C7,
                    C8, C9, C10, C11;
          traits.initAcc(C0);  traits.initAcc(C1);  traits.initAcc(C2);  traits.initAcc(C3);
00007FF6F87D4F05  vmovupd     ymm8,ymm1 
00007FF6F87D4F09  vmovupd     ymm10,ymm1 
00007FF6F87D4F0D  vmovupd     ymm13,ymm1 
00007FF6F87D4F11  vmovupd     ymmword ptr [C3],ymm9 
          traits.initAcc(C4);  traits.initAcc(C5);  traits.initAcc(C6);  traits.initAcc(C7);
00007FF6F87D4F19  vmovupd     ymm11,ymm1 
00007FF6F87D4F1D  vmovupd     ymm12,ymm1 
00007FF6F87D4F21  vmovupd     ymm14,ymm1 
00007FF6F87D4F25  vmovupd     ymmword ptr [C7],ymm15 
          traits.initAcc(C8);  traits.initAcc(C9);  traits.initAcc(C10); traits.initAcc(C11);
00007FF6F87D4F2D  vmovupd     ymmword ptr [C8],ymm2 
00007FF6F87D4F35  vmovupd     ymmword ptr [C9],ymm1 
00007FF6F87D4F3D  vmovupd     ymmword ptr [C10],ymm1 
00007FF6F87D4F45  vmovupd     ymmword ptr [C11],ymm6 

          r0.prefetch(0);
00007FF6F87D4F4D  prefetcht0  [rcx+r10*8] 
          r1.prefetch(0);
00007FF6F87D4F52  prefetcht0  [rcx+r11*8] 
          r2.prefetch(0);
00007FF6F87D4F57  prefetcht0  [rcx+rbx*8] 
          r3.prefetch(0);
00007FF6F87D4F5B  prefetcht0  [rcx+rdi*8] 

          // performs "inner" products
          const RhsScalar* blB = &blockB[j2*strideB+offsetB*nr];
00007FF6F87D4F5F  mov         rdx,qword ptr [rbp+18h] 
          prefetch(&blB[0]);
00007FF6F87D4F63  prefetcht0  [rdx] 
          LhsPacket A0, A1;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D4F66  test        r8,r8 
00007FF6F87D4F69  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+931h (07FF6F87D55B1h) 
          {
         
          // We selected a 3*Traits::LhsProgress x nr micro block of res which is entirely
          // stored into 3 x nr registers.
         
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(3*LhsProgress)];
00007FF6F87D4F6F  lea         rax,[r8-1] 
00007FF6F87D4F73  shr         rax,3 
00007FF6F87D4F77  inc         rax 
00007FF6F87D4F7A  nop         word ptr [rax+rax] 
          {
            EIGEN_ASM_COMMENT("begin gebp micro kernel 3pX4");
            RhsPacket B_0, T0;
            LhsPacket A2;

#define EIGEN_GEBP_ONESTEP(K) \
            do { \
              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 3pX4"); \
              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
              internal::prefetch(blA+(3*K+16)*LhsProgress); \
              if (EIGEN_ARCH_ARM) internal::prefetch(blB+(4*K+16)*RhsProgress); /* Bug 953 */ \
              traits.loadLhs(&blA[(0+3*K)*LhsProgress], A0);  \
              traits.loadLhs(&blA[(1+3*K)*LhsProgress], A1);  \
              traits.loadLhs(&blA[(2+3*K)*LhsProgress], A2);  \
              possiblyRotatingKernelHelper.template loadOrRotateRhs<K, 0>(B_0, blB); \
              traits.madd(A0, B_0, C0, T0); \
              traits.madd(A1, B_0, C4, T0); \
              traits.madd(A2, B_0, C8, B_0); \
              possiblyRotatingKernelHelper.template loadOrRotateRhs<K, 1>(B_0, blB); \
              traits.madd(A0, B_0, C1, T0); \
              traits.madd(A1, B_0, C5, T0); \
              traits.madd(A2, B_0, C9, B_0); \
              possiblyRotatingKernelHelper.template loadOrRotateRhs<K, 2>(B_0, blB); \
              traits.madd(A0, B_0, C2,  T0); \
              traits.madd(A1, B_0, C6,  T0); \
              traits.madd(A2, B_0, C10, B_0); \
              possiblyRotatingKernelHelper.template loadOrRotateRhs<K, 3>(B_0, blB); \
              traits.madd(A0, B_0, C3 , T0); \
              traits.madd(A1, B_0, C7,  T0); \
              traits.madd(A2, B_0, C11, B_0); \
              EIGEN_ASM_COMMENT("end step of gebp micro kernel 3pX4"); \
            } while(false)

            internal::prefetch(blB);
00007FF6F87D4F80  prefetcht0  [rdx] 
            EIGEN_GEBP_ONESTEP(0);
00007FF6F87D4F83  prefetcht0  [r9+200h] 
00007FF6F87D4F8B  vmovupd     ymm0,ymmword ptr [r9+40h] 
00007FF6F87D4F91  vmovupd     ymm4,ymmword ptr [r9] 
00007FF6F87D4F96  vmovupd     ymm5,ymmword ptr [r9+20h] 
00007FF6F87D4F9C  vbroadcastsd ymm1,mmword ptr [rdx] 
00007FF6F87D4FA1  vmovupd     ymm15,ymmword ptr [C10] 
00007FF6F87D4FA9  vfmadd231pd ymm2,ymm0,ymm1 
00007FF6F87D4FAE  vmovupd     ymm6,ymm0 
00007FF6F87D4FB2  vmovupd     ymm7,ymm8 
00007FF6F87D4FB7  vmovupd     ymm8,ymm11 
00007FF6F87D4FBC  vfmadd231pd ymm8,ymm5,ymm1 
00007FF6F87D4FC1  vfmadd231pd ymm7,ymm4,ymm1 
00007FF6F87D4FC6  vbroadcastsd ymm1,mmword ptr [rdx+8] 
00007FF6F87D4FCC  vmovupd     ymm11,ymm12 
00007FF6F87D4FD1  vmovupd     ymm12,ymmword ptr [C9] 
00007FF6F87D4FD9  vfmadd231pd ymm12,ymm0,ymm1 
00007FF6F87D4FDE  vfmadd231pd ymm10,ymm4,ymm1 
00007FF6F87D4FE3  vfmadd231pd ymm11,ymm5,ymm1 
00007FF6F87D4FE8  vbroadcastsd ymm1,mmword ptr [rdx+10h] 
00007FF6F87D4FEE  vfmadd231pd ymm15,ymm0,ymm1 
00007FF6F87D4FF3  vmovupd     ymm0,ymmword ptr [C3] 
00007FF6F87D4FFB  vfmadd231pd ymm13,ymm4,ymm1 
00007FF6F87D5000  vfmadd231pd ymm14,ymm5,ymm1 
00007FF6F87D5005  vbroadcastsd ymm1,mmword ptr [rdx+18h] 
00007FF6F87D500B  vfmadd231pd ymm0,ymm4,ymm1 
00007FF6F87D5010  vmovupd     ymmword ptr [C5],ymm0 
00007FF6F87D5018  vmovupd     ymm0,ymmword ptr [C7] 
00007FF6F87D5020  vfmadd231pd ymm0,ymm5,ymm1 
00007FF6F87D5025  vmovupd     ymmword ptr [C4],ymm0 
00007FF6F87D502D  vmovupd     ymm0,ymmword ptr [C11] 
00007FF6F87D5035  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D503A  vmovupd     ymmword ptr [C0],ymm0 
00007FF6F87D5042  vmovupd     ymm9,ymm2 
            EIGEN_GEBP_ONESTEP(1);
00007FF6F87D5046  prefetcht0  [r9+260h] 
00007FF6F87D504E  vmovupd     ymm0,ymmword ptr [r9+0A0h] 
00007FF6F87D5057  vmovupd     ymm4,ymmword ptr [r9+60h] 
00007FF6F87D505D  vmovupd     ymm5,ymmword ptr [r9+80h] 
00007FF6F87D5066  vbroadcastsd ymm1,mmword ptr [rdx+20h] 
00007FF6F87D506C  vfmadd231pd ymm9,ymm0,ymm1 
00007FF6F87D5071  vmovupd     ymm6,ymm0 
00007FF6F87D5075  vfmadd231pd ymm7,ymm4,ymm1 
00007FF6F87D507A  vfmadd231pd ymm8,ymm5,ymm1 
00007FF6F87D507F  vbroadcastsd ymm1,mmword ptr [rdx+28h] 
00007FF6F87D5085  vfmadd231pd ymm12,ymm0,ymm1 
00007FF6F87D508A  vfmadd231pd ymm10,ymm4,ymm1 
00007FF6F87D508F  vfmadd231pd ymm11,ymm5,ymm1 
00007FF6F87D5094  vbroadcastsd ymm1,mmword ptr [rdx+30h] 
00007FF6F87D509A  vfmadd231pd ymm15,ymm0,ymm1 
00007FF6F87D509F  vmovupd     ymm0,ymmword ptr [C3] 
00007FF6F87D50A7  vfmadd231pd ymm13,ymm4,ymm1 
00007FF6F87D50AC  vfmadd231pd ymm14,ymm5,ymm1 
00007FF6F87D50B1  vbroadcastsd ymm1,mmword ptr [rdx+38h] 
00007FF6F87D50B7  vfmadd231pd ymm0,ymm4,ymm1 
00007FF6F87D50BC  vmovupd     ymmword ptr [C3],ymm0 
00007FF6F87D50C4  vmovupd     ymm0,ymmword ptr [C7] 
00007FF6F87D50CC  vfmadd231pd ymm0,ymm5,ymm1 
00007FF6F87D50D1  vmovupd     ymmword ptr [C7],ymm0 
00007FF6F87D50D9  vmovupd     ymm0,ymmword ptr [C11] 
00007FF6F87D50E1  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D50E6  vmovupd     ymmword ptr [C11],ymm0 
            EIGEN_GEBP_ONESTEP(2);
00007FF6F87D50EE  prefetcht0  [r9+2C0h] 
00007FF6F87D50F6  vmovupd     ymm0,ymmword ptr [r9+100h] 
00007FF6F87D50FF  vmovupd     ymm4,ymmword ptr [r9+0C0h] 
00007FF6F87D5108  vmovupd     ymm5,ymmword ptr [r9+0E0h] 
00007FF6F87D5111  vbroadcastsd ymm1,mmword ptr [rdx+40h] 
00007FF6F87D5117  vfmadd231pd ymm9,ymm0,ymm1 
00007FF6F87D511C  vmovupd     ymm6,ymm0 
00007FF6F87D5120  vfmadd231pd ymm7,ymm4,ymm1 
00007FF6F87D5125  vfmadd231pd ymm8,ymm5,ymm1 
00007FF6F87D512A  vbroadcastsd ymm1,mmword ptr [rdx+48h] 
00007FF6F87D5130  vfmadd231pd ymm12,ymm0,ymm1 
00007FF6F87D5135  vfmadd231pd ymm10,ymm4,ymm1 
00007FF6F87D513A  vfmadd231pd ymm11,ymm5,ymm1 
00007FF6F87D513F  vbroadcastsd ymm1,mmword ptr [rdx+50h] 
00007FF6F87D5145  vfmadd231pd ymm15,ymm0,ymm1 
00007FF6F87D514A  vmovupd     ymm0,ymmword ptr [C3] 
00007FF6F87D5152  vfmadd231pd ymm13,ymm4,ymm1 
00007FF6F87D5157  vfmadd231pd ymm14,ymm5,ymm1 
00007FF6F87D515C  vbroadcastsd ymm1,mmword ptr [rdx+58h] 
00007FF6F87D5162  vfmadd231pd ymm0,ymm4,ymm1 
00007FF6F87D5167  vmovupd     ymmword ptr [C3],ymm0 
00007FF6F87D516F  vmovupd     ymm0,ymmword ptr [C7] 
00007FF6F87D5177  vfmadd231pd ymm0,ymm5,ymm1 
00007FF6F87D517C  vmovupd     ymmword ptr [C7],ymm0 
00007FF6F87D5184  vmovupd     ymm0,ymmword ptr [C11] 
00007FF6F87D518C  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D5191  vmovupd     ymmword ptr [C11],ymm0 
            EIGEN_GEBP_ONESTEP(3);
00007FF6F87D5199  prefetcht0  [r9+320h] 
00007FF6F87D51A1  vmovupd     ymm0,ymmword ptr [r9+160h] 
00007FF6F87D51AA  vmovupd     ymm4,ymmword ptr [r9+120h] 
00007FF6F87D51B3  vmovupd     ymm5,ymmword ptr [r9+140h] 
00007FF6F87D51BC  vbroadcastsd ymm1,mmword ptr [rdx+60h] 
00007FF6F87D51C2  vfmadd231pd ymm9,ymm0,ymm1 
00007FF6F87D51C7  vmovupd     ymm6,ymm0 
00007FF6F87D51CB  vfmadd231pd ymm7,ymm4,ymm1 
00007FF6F87D51D0  vfmadd231pd ymm8,ymm5,ymm1 
00007FF6F87D51D5  vbroadcastsd ymm1,mmword ptr [rdx+68h] 
00007FF6F87D51DB  vfmadd231pd ymm12,ymm0,ymm1 
00007FF6F87D51E0  vfmadd231pd ymm10,ymm4,ymm1 
00007FF6F87D51E5  vfmadd231pd ymm11,ymm5,ymm1 
00007FF6F87D51EA  vbroadcastsd ymm1,mmword ptr [rdx+70h] 
00007FF6F87D51F0  vfmadd231pd ymm15,ymm0,ymm1 
00007FF6F87D51F5  vmovupd     ymm0,ymmword ptr [C3] 
00007FF6F87D51FD  vfmadd231pd ymm13,ymm4,ymm1 
00007FF6F87D5202  vfmadd231pd ymm14,ymm5,ymm1 
00007FF6F87D5207  vbroadcastsd ymm1,mmword ptr [rdx+78h] 
00007FF6F87D520D  vfmadd231pd ymm0,ymm4,ymm1 
00007FF6F87D5212  vmovupd     ymmword ptr [C3],ymm0 
00007FF6F87D521A  vmovupd     ymm0,ymmword ptr [C7] 
00007FF6F87D5222  vfmadd231pd ymm0,ymm5,ymm1 
00007FF6F87D5227  vmovupd     ymmword ptr [C7],ymm0 
00007FF6F87D522F  vmovupd     ymm0,ymmword ptr [C11] 
00007FF6F87D5237  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D523C  vmovupd     ymmword ptr [C11],ymm0 
            EIGEN_GEBP_ONESTEP(4);
00007FF6F87D5244  prefetcht0  [r9+380h] 
00007FF6F87D524C  vmovupd     ymm0,ymmword ptr [r9+1C0h] 
00007FF6F87D5255  vmovupd     ymm4,ymmword ptr [r9+180h] 
00007FF6F87D525E  vmovupd     ymm5,ymmword ptr [r9+1A0h] 
00007FF6F87D5267  vbroadcastsd ymm1,mmword ptr [rdx+80h] 
00007FF6F87D5270  vfmadd231pd ymm9,ymm0,ymm1 
00007FF6F87D5275  vmovupd     ymm6,ymm0 
00007FF6F87D5279  vfmadd231pd ymm7,ymm4,ymm1 
00007FF6F87D527E  vfmadd231pd ymm8,ymm5,ymm1 
00007FF6F87D5283  vbroadcastsd ymm1,mmword ptr [rdx+88h] 
00007FF6F87D528C  vfmadd231pd ymm12,ymm0,ymm1 
00007FF6F87D5291  vfmadd231pd ymm10,ymm4,ymm1 
00007FF6F87D5296  vfmadd231pd ymm11,ymm5,ymm1 
00007FF6F87D529B  vbroadcastsd ymm1,mmword ptr [rdx+90h] 
00007FF6F87D52A4  vfmadd231pd ymm15,ymm0,ymm1 
00007FF6F87D52A9  vmovupd     ymm0,ymmword ptr [C3] 
00007FF6F87D52B1  vfmadd231pd ymm13,ymm4,ymm1 
00007FF6F87D52B6  vfmadd231pd ymm14,ymm5,ymm1 
00007FF6F87D52BB  vbroadcastsd ymm1,mmword ptr [rdx+98h] 
00007FF6F87D52C4  vfmadd231pd ymm0,ymm4,ymm1 
00007FF6F87D52C9  vmovupd     ymmword ptr [C3],ymm0 
00007FF6F87D52D1  vmovupd     ymm0,ymmword ptr [C7] 
00007FF6F87D52D9  vfmadd231pd ymm0,ymm5,ymm1 
00007FF6F87D52DE  vmovupd     ymmword ptr [C7],ymm0 
00007FF6F87D52E6  vmovupd     ymm0,ymmword ptr [C11] 
00007FF6F87D52EE  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D52F3  vmovupd     ymmword ptr [C11],ymm0 
            EIGEN_GEBP_ONESTEP(5);
00007FF6F87D52FB  prefetcht0  [r9+3E0h] 
00007FF6F87D5303  vmovupd     ymm0,ymmword ptr [r9+220h] 
00007FF6F87D530C  vmovupd     ymm4,ymmword ptr [r9+1E0h] 
00007FF6F87D5315  vmovupd     ymm5,ymmword ptr [r9+200h] 
00007FF6F87D531E  vbroadcastsd ymm1,mmword ptr [rdx+0A0h] 
00007FF6F87D5327  vfmadd231pd ymm9,ymm0,ymm1 
00007FF6F87D532C  vmovupd     ymm6,ymm0 
00007FF6F87D5330  vfmadd231pd ymm7,ymm4,ymm1 
00007FF6F87D5335  vfmadd231pd ymm8,ymm5,ymm1 
00007FF6F87D533A  vbroadcastsd ymm1,mmword ptr [rdx+0A8h] 
00007FF6F87D5343  vfmadd231pd ymm12,ymm0,ymm1 
00007FF6F87D5348  vfmadd231pd ymm10,ymm4,ymm1 
00007FF6F87D534D  vfmadd231pd ymm11,ymm5,ymm1 
00007FF6F87D5352  vbroadcastsd ymm1,mmword ptr [rdx+0B0h] 
00007FF6F87D535B  vfmadd231pd ymm15,ymm0,ymm1 
00007FF6F87D5360  vmovupd     ymm0,ymmword ptr [C3] 
00007FF6F87D5368  vfmadd231pd ymm13,ymm4,ymm1 
00007FF6F87D536D  vfmadd231pd ymm14,ymm5,ymm1 
00007FF6F87D5372  vbroadcastsd ymm1,mmword ptr [rdx+0B8h] 
00007FF6F87D537B  vfmadd231pd ymm0,ymm4,ymm1 
00007FF6F87D5380  vmovupd     ymmword ptr [C3],ymm0 
00007FF6F87D5388  vmovupd     ymm0,ymmword ptr [C7] 
00007FF6F87D5390  vfmadd231pd ymm0,ymm5,ymm1 
00007FF6F87D5395  vmovupd     ymmword ptr [C7],ymm0 
00007FF6F87D539D  vmovupd     ymm0,ymmword ptr [C11] 
00007FF6F87D53A5  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D53AA  vmovupd     ymmword ptr [C11],ymm0 
            EIGEN_GEBP_ONESTEP(6);
00007FF6F87D53B2  prefetcht0  [r9+440h] 
00007FF6F87D53BA  vmovupd     ymm0,ymmword ptr [r9+280h] 
00007FF6F87D53C3  vmovupd     ymm4,ymmword ptr [r9+240h] 
00007FF6F87D53CC  vmovupd     ymm5,ymmword ptr [r9+260h] 
00007FF6F87D53D5  vbroadcastsd ymm1,mmword ptr [rdx+0C0h] 
00007FF6F87D53DE  vfmadd231pd ymm9,ymm0,ymm1 
00007FF6F87D53E3  vmovupd     ymm6,ymm0 
00007FF6F87D53E7  vfmadd231pd ymm7,ymm4,ymm1 
00007FF6F87D53EC  vfmadd231pd ymm8,ymm5,ymm1 
00007FF6F87D53F1  vbroadcastsd ymm1,mmword ptr [rdx+0C8h] 
00007FF6F87D53FA  vfmadd231pd ymm12,ymm0,ymm1 
00007FF6F87D53FF  vfmadd231pd ymm10,ymm4,ymm1 
00007FF6F87D5404  vfmadd231pd ymm11,ymm5,ymm1 
00007FF6F87D5409  vbroadcastsd ymm1,mmword ptr [rdx+0D0h] 
00007FF6F87D5412  vfmadd231pd ymm15,ymm0,ymm1 
00007FF6F87D5417  vmovupd     ymm0,ymmword ptr [C3] 
00007FF6F87D541F  vfmadd231pd ymm13,ymm4,ymm1 
00007FF6F87D5424  vfmadd231pd ymm14,ymm5,ymm1 
00007FF6F87D5429  vbroadcastsd ymm1,mmword ptr [rdx+0D8h] 
00007FF6F87D5432  vfmadd231pd ymm0,ymm4,ymm1 
00007FF6F87D5437  vmovupd     ymmword ptr [C7],ymm0 
00007FF6F87D543F  vmovupd     ymm0,ymmword ptr [C7] 
00007FF6F87D5447  vfmadd231pd ymm0,ymm5,ymm1 
00007FF6F87D544C  vmovupd     ymmword ptr [C11],ymm0 
00007FF6F87D5454  vmovupd     ymm0,ymmword ptr [C11] 
00007FF6F87D545C  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D5461  vmovupd     ymmword ptr [C11],ymm0 
            EIGEN_GEBP_ONESTEP(7);
00007FF6F87D5469  prefetcht0  [r9+4A0h] 
00007FF6F87D5471  vmovupd     ymm6,ymmword ptr [r9+2E0h] 
00007FF6F87D547A  vmovupd     ymm4,ymmword ptr [r9+2A0h] 
00007FF6F87D5483  vbroadcastsd ymm1,mmword ptr [rdx+0E0h] 
00007FF6F87D548C  vmovupd     ymm5,ymmword ptr [r9+2C0h] 
00007FF6F87D5495  vmovupd     ymm2,ymmword ptr [C11] 
00007FF6F87D549D  vmovupd     ymm3,ymm1 
00007FF6F87D54A1  vmovupd     ymm0,ymm7 
00007FF6F87D54A5  vfmadd231pd ymm0,ymm4,ymm1 
00007FF6F87D54AA  vmovupd     ymmword ptr [C11],ymm0 
00007FF6F87D54B2  vmovupd     ymm0,ymm8 
          LhsPacket A0, A1;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D54B7  vmovupd     ymm8,ymmword ptr [C0] 
            EIGEN_GEBP_ONESTEP(7);
00007FF6F87D54BF  vfmadd231pd ymm0,ymm5,ymm1 
00007FF6F87D54C4  vmovupd     ymmword ptr [C7],ymm0 
00007FF6F87D54CC  vmovupd     ymm1,ymm9 
00007FF6F87D54D1  vmovupd     ymm9,ymmword ptr [C3] 
00007FF6F87D54D9  vfmadd231pd ymm1,ymm6,ymm3 
00007FF6F87D54DE  vmovupd     ymmword ptr [C8],ymm1 
00007FF6F87D54E6  vbroadcastsd ymm1,mmword ptr [rdx+0E8h] 
00007FF6F87D54EF  vmovupd     ymm0,ymm11 
          LhsPacket A0, A1;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D54F4  vmovupd     ymm11,ymmword ptr [C4] 
            EIGEN_GEBP_ONESTEP(7);
00007FF6F87D54FC  vfmadd231pd ymm0,ymm5,ymm1 
00007FF6F87D5501  vmovupd     ymmword ptr [C3],ymm0 
00007FF6F87D5509  vmovupd     ymm0,ymm12 
          LhsPacket A0, A1;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D550E  vmovupd     ymm12,ymmword ptr [C5] 
            EIGEN_GEBP_ONESTEP(7);
00007FF6F87D5516  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D551B  vmovupd     ymmword ptr [C9],ymm0 
00007FF6F87D5523  vmovupd     ymm0,ymm15 
00007FF6F87D5528  vmovupd     ymm15,ymmword ptr [C7] 
00007FF6F87D5530  vfmadd231pd ymm10,ymm4,ymm1 
00007FF6F87D5535  vbroadcastsd ymm1,mmword ptr [rdx+0F0h] 
00007FF6F87D553E  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D5543  vfmadd231pd ymm13,ymm4,ymm1 
00007FF6F87D5548  vfmadd231pd ymm14,ymm5,ymm1 
00007FF6F87D554D  vbroadcastsd ymm1,mmword ptr [rdx+0F8h] 
00007FF6F87D5556  vfmadd231pd ymm2,ymm6,ymm1 
00007FF6F87D555B  vmovupd     ymm6,ymm2 
          LhsPacket A0, A1;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D555F  vmovupd     ymm2,ymmword ptr [C8] 

            blB += pk*4*RhsProgress;
00007FF6F87D5567  add         rdx,100h 
            blA += pk*3*Traits::LhsProgress;
00007FF6F87D556E  add         r9,300h 
            EIGEN_GEBP_ONESTEP(7);
00007FF6F87D5575  vfmadd231pd ymm9,ymm4,ymm1 
00007FF6F87D557A  vfmadd231pd ymm15,ymm5,ymm1 
00007FF6F87D557F  vmovupd     ymmword ptr [C7],ymm6 
00007FF6F87D5587  vmovupd     ymmword ptr [C10],ymm0 
00007FF6F87D558F  vmovupd     ymmword ptr [C3],ymm9 
00007FF6F87D5597  vmovupd     ymmword ptr [C3],ymm15 
          LhsPacket A0, A1;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D559F  sub         rax,1 
00007FF6F87D55A3  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+300h (07FF6F87D4F80h) 
00007FF6F87D55A9  vmovupd     ymm7,ymmword ptr [alphav] 

            EIGEN_ASM_COMMENT("end gebp micro kernel 3pX4");
          }
          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D55B1  cmp         r8,rsi 
00007FF6F87D55B4  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0A23h (07FF6F87D56A3h) 
00007FF6F87D55BA  vmovupd     ymm7,ymmword ptr [C9] 
00007FF6F87D55C2  lea         rax,[rdx+10h] 
00007FF6F87D55C6  lea         rdx,[r9+20h] 
00007FF6F87D55CA  mov         r9,rsi 
00007FF6F87D55CD  sub         r9,r8 
00007FF6F87D55D0  jmp         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+968h (07FF6F87D55E8h) 
00007FF6F87D55D2  nop         dword ptr [rax] 
00007FF6F87D55D6  nop         word ptr [rax+rax] 
00007FF6F87D55E0  vmovupd     ymm2,ymmword ptr [C8] 
          {
            RhsPacket B_0, T0;
            LhsPacket A2;
            EIGEN_GEBP_ONESTEP(0);
00007FF6F87D55E8  prefetcht0  [rdx+1E0h] 
00007FF6F87D55EF  vmovupd     ymm6,ymmword ptr [rdx+20h] 
00007FF6F87D55F4  vbroadcastsd ymm1,mmword ptr [rax-10h] 
            blB += 4*RhsProgress;
00007FF6F87D55FA  lea         rax,[rax+20h] 
          {
            RhsPacket B_0, T0;
            LhsPacket A2;
            EIGEN_GEBP_ONESTEP(0);
00007FF6F87D55FE  vmovupd     ymm4,ymmword ptr [rdx-20h] 
00007FF6F87D5603  vmovupd     ymm5,ymmword ptr [rdx] 
            blA += 3*Traits::LhsProgress;
00007FF6F87D5607  lea         rdx,[rdx+60h] 
          {
            RhsPacket B_0, T0;
            LhsPacket A2;
            EIGEN_GEBP_ONESTEP(0);
00007FF6F87D560B  vfmadd231pd ymm2,ymm1,ymm6 
00007FF6F87D5610  vmovupd     ymm0,ymm2 
00007FF6F87D5614  vmovupd     ymm2,ymmword ptr [C11] 
00007FF6F87D561C  vfmadd231pd ymm8,ymm1,ymm4 
00007FF6F87D5621  vfmadd231pd ymm11,ymm5,ymm1 
00007FF6F87D5626  vbroadcastsd ymm1,mmword ptr [rax-28h] 
00007FF6F87D562C  vfmadd231pd ymm7,ymm6,ymm1 
00007FF6F87D5631  vmovupd     ymmword ptr [C8],ymm0 
00007FF6F87D5639  vmovupd     ymm0,ymmword ptr [C10] 
00007FF6F87D5641  vfmadd231pd ymm10,ymm4,ymm1 
00007FF6F87D5646  vfmadd231pd ymm12,ymm5,ymm1 
00007FF6F87D564B  vbroadcastsd ymm1,mmword ptr [rax-20h] 
00007FF6F87D5651  vfmadd231pd ymm0,ymm6,ymm1 
00007FF6F87D5656  vfmadd231pd ymm13,ymm4,ymm1 
00007FF6F87D565B  vfmadd231pd ymm14,ymm5,ymm1 
00007FF6F87D5660  vbroadcastsd ymm1,mmword ptr [rax-18h] 
00007FF6F87D5666  vfmadd231pd ymm2,ymm6,ymm1 
00007FF6F87D566B  vmovupd     ymm6,ymm2 
00007FF6F87D566F  vmovupd     ymmword ptr [C11],ymm6 
00007FF6F87D5677  vmovupd     ymmword ptr [C9],ymm7 
00007FF6F87D567F  vmovupd     ymmword ptr [C10],ymm0 
00007FF6F87D5687  vfmadd231pd ymm9,ymm4,ymm1 
00007FF6F87D568C  vfmadd231pd ymm15,ymm5,ymm1 

            EIGEN_ASM_COMMENT("end gebp micro kernel 3pX4");
          }
          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D5691  sub         r9,1 
00007FF6F87D5695  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+960h (07FF6F87D55E0h) 
00007FF6F87D569B  vmovupd     ymm7,ymmword ptr [alphav] 
          traits.acc(C0, alphav, R0);
00007FF6F87D56A3  vmovupd     ymm0,ymmword ptr [rcx+r10*8] 

          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
          R1 = r0.loadPacket(1 * Traits::ResPacketSize);
00007FF6F87D56A9  vmovupd     ymm4,ymmword ptr [rcx+r10*8+20h] 
          R2 = r0.loadPacket(2 * Traits::ResPacketSize);
00007FF6F87D56B0  vmovupd     ymm3,ymmword ptr [rcx+r10*8+40h] 
          traits.acc(C8, alphav, R2);
00007FF6F87D56B7  vfmadd231pd ymm3,ymm7,ymmword ptr [C8] 
        {
          for(Index i=i1; i<actual_panel_end; i+=3*LhsProgress)
00007FF6F87D56C0  add         r12,qword ptr [rbp+58h] 
00007FF6F87D56C4  lea         rdx,[r13-1] 
00007FF6F87D56C8  vmovupd     ymm1,ymmword ptr [rbp+200h] 
          traits.acc(C0, alphav, R0);
00007FF6F87D56D0  vfmadd231pd ymm0,ymm8,ymm7 
          r0.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D56D5  vmovupd     ymmword ptr [rcx+r10*8],ymm0 
          traits.acc(C4, alphav, R1);
00007FF6F87D56DB  vfmadd231pd ymm4,ymm11,ymm7 
          r0.storePacket(1 * Traits::ResPacketSize, R1);
00007FF6F87D56E0  vmovupd     ymmword ptr [rcx+r10*8+20h],ymm4 
          r0.storePacket(2 * Traits::ResPacketSize, R2);
00007FF6F87D56E7  vmovupd     ymmword ptr [rcx+r10*8+40h],ymm3 
          traits.acc(C1, alphav, R0);
00007FF6F87D56EE  vmovupd     ymm0,ymmword ptr [rcx+r11*8] 

          R0 = r1.loadPacket(0 * Traits::ResPacketSize);
          R1 = r1.loadPacket(1 * Traits::ResPacketSize);
00007FF6F87D56F4  vmovupd     ymm4,ymmword ptr [rcx+r11*8+20h] 
          R2 = r1.loadPacket(2 * Traits::ResPacketSize);
00007FF6F87D56FB  vmovupd     ymm3,ymmword ptr [rcx+r11*8+40h] 
          traits.acc(C9, alphav, R2);
00007FF6F87D5702  vfmadd231pd ymm3,ymm7,ymmword ptr [C9] 
          traits.acc(C1, alphav, R0);
00007FF6F87D570B  vfmadd231pd ymm0,ymm10,ymm7 
          r1.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D5710  vmovupd     ymmword ptr [rcx+r11*8],ymm0 
          traits.acc(C5, alphav, R1);
00007FF6F87D5716  vfmadd231pd ymm4,ymm12,ymm7 
          r1.storePacket(1 * Traits::ResPacketSize, R1);
00007FF6F87D571B  vmovupd     ymmword ptr [rcx+r11*8+20h],ymm4 
          r1.storePacket(2 * Traits::ResPacketSize, R2);
00007FF6F87D5722  vmovupd     ymmword ptr [rcx+r11*8+40h],ymm3 
          traits.acc(C2, alphav, R0);
00007FF6F87D5729  vmovupd     ymm0,ymmword ptr [rcx+rbx*8] 

          R0 = r2.loadPacket(0 * Traits::ResPacketSize);
          R1 = r2.loadPacket(1 * Traits::ResPacketSize);
00007FF6F87D572E  vmovupd     ymm4,ymmword ptr [rcx+rbx*8+20h] 
          R2 = r2.loadPacket(2 * Traits::ResPacketSize);
00007FF6F87D5734  vmovupd     ymm3,ymmword ptr [rcx+rbx*8+40h] 
          traits.acc(C10, alphav, R2);
00007FF6F87D573A  vfmadd231pd ymm3,ymm7,ymmword ptr [C10] 
          traits.acc(C2, alphav, R0);
00007FF6F87D5743  vfmadd231pd ymm0,ymm13,ymm7 
          r2.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D5748  vmovupd     ymmword ptr [rcx+rbx*8],ymm0 
          traits.acc(C6, alphav, R1);
00007FF6F87D574D  vfmadd231pd ymm4,ymm14,ymm7 
          r2.storePacket(1 * Traits::ResPacketSize, R1);
00007FF6F87D5752  vmovupd     ymmword ptr [rcx+rbx*8+20h],ymm4 
          r2.storePacket(2 * Traits::ResPacketSize, R2);
00007FF6F87D5758  vmovupd     ymmword ptr [rcx+rbx*8+40h],ymm3 
          traits.acc(C3, alphav, R0);
00007FF6F87D575E  vmovupd     ymm0,ymmword ptr [rcx+rdi*8] 

          R0 = r3.loadPacket(0 * Traits::ResPacketSize);
          R1 = r3.loadPacket(1 * Traits::ResPacketSize);
00007FF6F87D5763  vmovupd     ymm4,ymmword ptr [rcx+rdi*8+20h] 
          R2 = r3.loadPacket(2 * Traits::ResPacketSize);
00007FF6F87D5769  vmovupd     ymm3,ymmword ptr [rcx+rdi*8+40h] 
          traits.acc(C3, alphav, R0);
00007FF6F87D576F  vfmadd231pd ymm0,ymm9,ymm7 
          r3.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D5774  vmovupd     ymmword ptr [rcx+rdi*8],ymm0 
          traits.acc(C7, alphav, R1);
00007FF6F87D5779  vfmadd231pd ymm4,ymm15,ymm7 
          r3.storePacket(1 * Traits::ResPacketSize, R1);
00007FF6F87D577E  vmovupd     ymmword ptr [rcx+rdi*8+20h],ymm4 
          traits.acc(C11, alphav, R2);
00007FF6F87D5784  vfmadd231pd ymm3,ymm6,ymm7 
        {
          for(Index i=i1; i<actual_panel_end; i+=3*LhsProgress)
00007FF6F87D5789  add         r15,0Ch 
          r3.storePacket(2 * Traits::ResPacketSize, R2);         
00007FF6F87D578D  vmovupd     ymmword ptr [rcx+rdi*8+40h],ymm3 
        {
          for(Index i=i1; i<actual_panel_end; i+=3*LhsProgress)
00007FF6F87D5793  lea         rdi,[r13+1] 
00007FF6F87D5797  cmp         r15,qword ptr [actual_panel_end] 
00007FF6F87D579B  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+240h (07FF6F87D4EC0h) 
00007FF6F87D57A1  vmovsd      xmm2,qword ptr [alpha] 
00007FF6F87D57A6  mov         r12,qword ptr [actual_panel_end] 
00007FF6F87D57AA  mov         rcx,qword ptr [i1] 
00007FF6F87D57AE  mov         r11,qword ptr [strideA] 
00007FF6F87D57B2  mov         rax,qword ptr [rbp] 
00007FF6F87D57B6  mov         rbx,qword ptr [j2] 
00007FF6F87D57BA  mov         rdx,qword ptr [rbp+60h] 
00007FF6F87D57BE  mov         r10,qword ptr [blockA] 
        for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D57C6  add         rax,rdx 
00007FF6F87D57C9  add         r13,4 
00007FF6F87D57CD  mov         qword ptr [rbp],rax 
00007FF6F87D57D1  lea         rax,[r13-2] 
00007FF6F87D57D5  cmp         rax,rbx 
00007FF6F87D57D8  mov         rax,qword ptr [rbp] 
00007FF6F87D57DC  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1D0h (07FF6F87D4E50h) 
00007FF6F87D57E2  mov         r9,qword ptr [peeled_mc3] 
00007FF6F87D57E9  mov         r13,qword ptr [blockB] 
00007FF6F87D57F1  mov         rdx,qword ptr [offsetB] 
00007FF6F87D57F9  mov         r15,qword ptr [strideB] 
          }
        }

        // Deal with remaining columns of the rhs
        for(Index j2=packet_cols4; j2<cols; j2++)
00007FF6F87D57FD  mov         rdi,rbx 
00007FF6F87D5800  cmp         rbx,qword ptr [cols] 
00007FF6F87D5808  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0DFEh (07FF6F87D5A7Eh) 
00007FF6F87D580E  lea         rax,[r15*8] 
00007FF6F87D5816  mov         qword ptr [actual_panel_end],rax 
00007FF6F87D581A  mov         rax,rbx 
00007FF6F87D581D  imul        rax,r15 
00007FF6F87D5821  add         rax,rdx 
00007FF6F87D5824  mov         rdx,qword ptr [cols] 
00007FF6F87D582C  lea         r13,[r13+rax*8] 
00007FF6F87D5831  mov         rax,qword ptr [rbp+38h] 
00007FF6F87D5835  nop         word ptr [rax+rax] 
        {
          for(Index i=i1; i<actual_panel_end; i+=3*LhsProgress)
00007FF6F87D5840  mov         rbx,rcx 
00007FF6F87D5843  cmp         rcx,r12 
00007FF6F87D5846  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0DD3h (07FF6F87D5A53h) 
00007FF6F87D584C  lea         r15,[r11+r11*2] 
00007FF6F87D5850  mov         rax,rcx 
00007FF6F87D5853  shl         r15,5 
00007FF6F87D5857  imul        rax,r11 
00007FF6F87D585B  vmovaps     xmm1,xmm2 
00007FF6F87D585F  vxorps      ymm9,ymm0,ymm0 
00007FF6F87D5863  vbroadcastsd ymm10,xmm1 
00007FF6F87D5868  lea         r11,[r10+rax*8] 
00007FF6F87D586C  nop         dword ptr [rax] 
          {
          // One column at a time
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(3*Traits::LhsProgress)];
00007FF6F87D5870  mov         rax,r11 
          prefetch(&blA[0]);
00007FF6F87D5873  prefetcht0  [r11] 

          LinearMapper r0 = res.getLinearMapper(i, j2);
00007FF6F87D5877  mov         r10,qword ptr [r14] 
00007FF6F87D587A  mov         rdx,rdi 
00007FF6F87D587D  imul        rdx,qword ptr [r14+8] 

          // gets res block as register
          AccPacket C0, C4, C8;
          traits.initAcc(C0);
00007FF6F87D5882  vmovupd     ymm6,ymm9 

          LinearMapper r0 = res.getLinearMapper(i, j2);
00007FF6F87D5887  add         rdx,rbx 
          traits.initAcc(C4);
00007FF6F87D588A  vmovupd     ymm7,ymm9 
          traits.initAcc(C8);
00007FF6F87D588F  vmovupd     ymm8,ymm9 
          r0.prefetch(0);
00007FF6F87D5894  prefetcht0  [r10+rdx*8] 

          // performs "inner" products
          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
          LhsPacket A0, A1, A2;
         
          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D5899  mov         rcx,r13 
00007FF6F87D589C  test        r8,r8 
00007FF6F87D589F  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0D3Eh (07FF6F87D59BEh) 
          {
          // One column at a time
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(3*Traits::LhsProgress)];
00007FF6F87D58A5  lea         r9,[r8-1] 
00007FF6F87D58A9  shr         r9,3 
00007FF6F87D58AD  inc         r9 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D58B0  vbroadcastsd ymm0,mmword ptr [rcx+8] 
          {
            EIGEN_ASM_COMMENT("begin gebp micro kernel 3pX1");
            RhsPacket B_0;
#define EIGEN_GEBGP_ONESTEP(K) \
            do { \
              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 3pX1"); \
              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
              traits.loadLhs(&blA[(0+3*K)*LhsProgress], A0);  \
              traits.loadLhs(&blA[(1+3*K)*LhsProgress], A1);  \
              traits.loadLhs(&blA[(2+3*K)*LhsProgress], A2);  \
              traits.loadRhs(&blB[(0+K)*RhsProgress], B_0);   \
              traits.madd(A0, B_0, C0, B_0); \
              traits.madd(A1, B_0, C4, B_0); \
              traits.madd(A2, B_0, C8, B_0); \
              EIGEN_ASM_COMMENT("end step of gebp micro kernel 3pX1"); \
            } while(false)
       
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D58B6  vbroadcastsd ymm1,mmword ptr [rcx] 
00007FF6F87D58BB  vfmadd231pd ymm6,ymm1,ymmword ptr [rax] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D58C0  vfmadd231pd ymm6,ymm0,ymmword ptr [rax+60h] 
          {
            EIGEN_ASM_COMMENT("begin gebp micro kernel 3pX1");
            RhsPacket B_0;
#define EIGEN_GEBGP_ONESTEP(K) \
            do { \
              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 3pX1"); \
              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
              traits.loadLhs(&blA[(0+3*K)*LhsProgress], A0);  \
              traits.loadLhs(&blA[(1+3*K)*LhsProgress], A1);  \
              traits.loadLhs(&blA[(2+3*K)*LhsProgress], A2);  \
              traits.loadRhs(&blB[(0+K)*RhsProgress], B_0);   \
              traits.madd(A0, B_0, C0, B_0); \
              traits.madd(A1, B_0, C4, B_0); \
              traits.madd(A2, B_0, C8, B_0); \
              EIGEN_ASM_COMMENT("end step of gebp micro kernel 3pX1"); \
            } while(false)
       
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D58C6  vfmadd231pd ymm7,ymm1,ymmword ptr [rax+20h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D58CC  vfmadd231pd ymm7,ymm0,ymmword ptr [rax+80h] 
          {
            EIGEN_ASM_COMMENT("begin gebp micro kernel 3pX1");
            RhsPacket B_0;
#define EIGEN_GEBGP_ONESTEP(K) \
            do { \
              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 3pX1"); \
              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
              traits.loadLhs(&blA[(0+3*K)*LhsProgress], A0);  \
              traits.loadLhs(&blA[(1+3*K)*LhsProgress], A1);  \
              traits.loadLhs(&blA[(2+3*K)*LhsProgress], A2);  \
              traits.loadRhs(&blB[(0+K)*RhsProgress], B_0);   \
              traits.madd(A0, B_0, C0, B_0); \
              traits.madd(A1, B_0, C4, B_0); \
              traits.madd(A2, B_0, C8, B_0); \
              EIGEN_ASM_COMMENT("end step of gebp micro kernel 3pX1"); \
            } while(false)
       
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D58D5  vfmadd231pd ymm8,ymm1,ymmword ptr [rax+40h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D58DB  vfmadd231pd ymm8,ymm0,ymmword ptr [rax+0A0h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D58E4  vbroadcastsd ymm0,mmword ptr [rcx+10h] 
00007FF6F87D58EA  vfmadd231pd ymm6,ymm0,ymmword ptr [rax+0C0h] 
00007FF6F87D58F3  vfmadd231pd ymm7,ymm0,ymmword ptr [rax+0E0h] 
00007FF6F87D58FC  vfmadd231pd ymm8,ymm0,ymmword ptr [rax+100h] 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D5905  vbroadcastsd ymm0,mmword ptr [rcx+18h] 
00007FF6F87D590B  vfmadd231pd ymm6,ymm0,ymmword ptr [rax+120h] 
00007FF6F87D5914  vfmadd231pd ymm7,ymm0,ymmword ptr [rax+140h] 
00007FF6F87D591D  vfmadd231pd ymm8,ymm0,ymmword ptr [rax+160h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D5926  vbroadcastsd ymm0,mmword ptr [rcx+20h] 
00007FF6F87D592C  vfmadd231pd ymm6,ymm0,ymmword ptr [rax+180h] 
00007FF6F87D5935  vfmadd231pd ymm7,ymm0,ymmword ptr [rax+1A0h] 
00007FF6F87D593E  vfmadd231pd ymm8,ymm0,ymmword ptr [rax+1C0h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D5947  vbroadcastsd ymm0,mmword ptr [rcx+28h] 
00007FF6F87D594D  vfmadd231pd ymm6,ymm0,ymmword ptr [rax+1E0h] 
00007FF6F87D5956  vfmadd231pd ymm7,ymm0,ymmword ptr [rax+200h] 
00007FF6F87D595F  vfmadd231pd ymm8,ymm0,ymmword ptr [rax+220h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D5968  vbroadcastsd ymm0,mmword ptr [rcx+30h] 
00007FF6F87D596E  vfmadd231pd ymm6,ymm0,ymmword ptr [rax+240h] 
00007FF6F87D5977  vfmadd231pd ymm7,ymm0,ymmword ptr [rax+260h] 
00007FF6F87D5980  vfmadd231pd ymm8,ymm0,ymmword ptr [rax+280h] 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D5989  vbroadcastsd ymm0,mmword ptr [rcx+38h] 
00007FF6F87D598F  vfmadd231pd ymm6,ymm0,ymmword ptr [rax+2A0h] 
00007FF6F87D5998  vfmadd231pd ymm7,ymm0,ymmword ptr [rax+2C0h] 
00007FF6F87D59A1  vfmadd231pd ymm8,ymm0,ymmword ptr [rax+2E0h] 

            blB += pk*RhsProgress;
            blA += pk*3*Traits::LhsProgress;
00007FF6F87D59AA  add         rax,300h 
00007FF6F87D59B0  add         rcx,40h 
00007FF6F87D59B4  sub         r9,1 
00007FF6F87D59B8  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0C30h (07FF6F87D58B0h) 

            EIGEN_ASM_COMMENT("end gebp micro kernel 3pX1");
          }

          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D59BE  cmp         r8,rsi 
00007FF6F87D59C1  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0D78h (07FF6F87D59F8h) 
00007FF6F87D59C3  add         rax,40h 
00007FF6F87D59C7  mov         r9,rsi 
00007FF6F87D59CA  sub         r9,r8 
00007FF6F87D59CD  nop         dword ptr [rax] 
            blA += 3*Traits::LhsProgress;
00007FF6F87D59D0  lea         rax,[rax+60h] 
          {
            RhsPacket B_0;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D59D4  vbroadcastsd ymm1,mmword ptr [rcx] 
            blB += RhsProgress;
00007FF6F87D59D9  lea         rcx,[rcx+8] 
          {
            RhsPacket B_0;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D59DD  vfmadd231pd ymm6,ymm1,ymmword ptr [rax-0A0h] 
00007FF6F87D59E6  vfmadd231pd ymm7,ymm1,ymmword ptr [rax-80h] 
00007FF6F87D59EC  vfmadd231pd ymm8,ymm1,ymmword ptr [rax-60h] 

            EIGEN_ASM_COMMENT("end gebp micro kernel 3pX1");
          }

          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D59F2  sub         r9,1 
00007FF6F87D59F6  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0D50h (07FF6F87D59D0h) 
          traits.acc(C0, alphav, R0);
00007FF6F87D59F8  vmovupd     ymm1,ymmword ptr [r10+rdx*8] 
          }
#undef EIGEN_GEBGP_ONESTEP
          ResPacket R0, R1, R2;
          ResPacket alphav = pset1<ResPacket>(alpha);

          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
          R1 = r0.loadPacket(1 * Traits::ResPacketSize);
00007FF6F87D59FE  vmovupd     ymm4,ymmword ptr [r10+rdx*8+20h] 
          R2 = r0.loadPacket(2 * Traits::ResPacketSize);
00007FF6F87D5A05  vmovupd     ymm3,ymmword ptr [r10+rdx*8+40h] 
          traits.acc(C0, alphav, R0);
00007FF6F87D5A0C  vfmadd231pd ymm1,ymm6,ymm10 
00007FF6F87D5A11  vmovupd     ymm0,ymm1 
          r0.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D5A15  vmovupd     ymmword ptr [r10+rdx*8],ymm0 
          traits.acc(C4, alphav, R1);
00007FF6F87D5A1B  vfmadd231pd ymm4,ymm7,ymm10 
        {
          for(Index i=i1; i<actual_panel_end; i+=3*LhsProgress)
00007FF6F87D5A20  add         rbx,0Ch 
00007FF6F87D5A24  add         r11,r15 
          traits.acc(C8, alphav, R2);
00007FF6F87D5A27  vfmadd231pd ymm3,ymm8,ymm10 
          r0.storePacket(1 * Traits::ResPacketSize, R1);
00007FF6F87D5A2C  vmovupd     ymmword ptr [r10+rdx*8+20h],ymm4 
          r0.storePacket(2 * Traits::ResPacketSize, R2);         
00007FF6F87D5A33  vmovupd     ymmword ptr [r10+rdx*8+40h],ymm3 
        {
          for(Index i=i1; i<actual_panel_end; i+=3*LhsProgress)
00007FF6F87D5A3A  cmp         rbx,r12 
00007FF6F87D5A3D  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0BF0h (07FF6F87D5870h) 
00007FF6F87D5A43  mov         rcx,qword ptr [i1] 
00007FF6F87D5A47  mov         rax,qword ptr [rbp+38h] 
00007FF6F87D5A4B  mov         rdx,qword ptr [cols] 
          }
        }

        // Deal with remaining columns of the rhs
        for(Index j2=packet_cols4; j2<cols; j2++)
00007FF6F87D5A53  vmovsd      xmm2,qword ptr [alpha] 
00007FF6F87D5A58  mov         r11,qword ptr [strideA] 
00007FF6F87D5A5C  inc         rdi 
00007FF6F87D5A5F  mov         r10,qword ptr [blockA] 
00007FF6F87D5A67  add         r13,rax 
00007FF6F87D5A6A  cmp         rdi,rdx 
00007FF6F87D5A6D  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0BC0h (07FF6F87D5840h) 
00007FF6F87D5A73  mov         r9,qword ptr [peeled_mc3] 
00007FF6F87D5A7A  mov         rbx,qword ptr [j2] 
      for(Index i1=0; i1<peeled_mc3; i1+=actual_panel_rows)
00007FF6F87D5A7E  mov         rcx,qword ptr [rbp+68h] 
00007FF6F87D5A82  mov         r11,qword ptr [strideA] 
00007FF6F87D5A86  mov         rax,qword ptr [actual_panel_rows] 
00007FF6F87D5A8A  mov         r10,qword ptr [blockA] 
00007FF6F87D5A92  mov         r13,qword ptr [blockB] 
00007FF6F87D5A9A  mov         rdx,qword ptr [offsetB] 
00007FF6F87D5AA2  mov         r15,qword ptr [strideB] 
00007FF6F87D5AA6  mov         qword ptr [i1],rcx 
00007FF6F87D5AAA  vmovsd      xmm2,qword ptr [alpha] 
00007FF6F87D5AAF  cmp         rcx,r9 
00007FF6F87D5AB2  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+193h (07FF6F87D4E13h) 
00007FF6F87D5AB8  mov         r12,qword ptr [peeled_mc2] 
00007FF6F87D5ABC  mov         qword ptr [rbp],r9 
          }
        }
      }
    }

    //---------- Process 2 * LhsProgress rows at once ----------
    if(mr>=2*Traits::LhsProgress)
    {
      const Index l1 = defaultL1CacheSize; // in Bytes, TODO, l1 should be passed to this function.
      // The max(1, ...) here is needed because we may be using blocking params larger than what our known l1 cache size
      // suggests we should be using: either because our known l1 cache size is inaccurate (e.g. on Android, we can only guess),
      // or because we are testing specific blocking sizes.
      Index actual_panel_rows = (2*LhsProgress) * std::max<Index>(1,( (l1 - sizeof(ResScalar)*mr*nr - depth*nr*sizeof(RhsScalar)) / (depth * sizeof(LhsScalar) * 2*LhsProgress) ));
00007FF6F87D5AC0  mov         rax,qword ptr [rbp+40h] 
00007FF6F87D5AC4  xor         edx,edx 
00007FF6F87D5AC6  mov         rcx,rsi 
00007FF6F87D5AC9  mov         qword ptr [rbp+1C8h],1 
00007FF6F87D5AD4  shl         rcx,6 
00007FF6F87D5AD8  div         rax,rcx 
00007FF6F87D5ADB  mov         ecx,1 
00007FF6F87D5AE0  cmp         rax,rcx 
00007FF6F87D5AE3  mov         qword ptr [rbp+1C0h],rax 
00007FF6F87D5AEA  cmovg       rcx,rax 
00007FF6F87D5AEE  shl         rcx,3 
00007FF6F87D5AF2  mov         qword ptr [rbp+58h],rcx 

      for(Index i1=peeled_mc3; i1<peeled_mc2; i1+=actual_panel_rows)
00007FF6F87D5AF6  cmp         r9,r12 
00007FF6F87D5AF9  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+180Bh (07FF6F87D648Bh) 
00007FF6F87D5AFF  vmovsd      xmm13,qword ptr [alpha] 
          }
        }
      }
    }
    //---------- Process 1 * LhsProgress rows at once ----------
    if(mr>=1*Traits::LhsProgress)
    {
      // loops on each largest micro horizontal panel of lhs (1*LhsProgress x depth)
      for(Index i=peeled_mc2; i<peeled_mc1; i+=1*LhsProgress)
00007FF6F87D5B04  cmp         r12,qword ptr [peeled_mc1] 
00007FF6F87D5B08  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+139Ah (07FF6F87D601Ah) 
00007FF6F87D5B0E  mov         r13,qword ptr [strideA] 
00007FF6F87D5B12  mov         rax,r12 
00007FF6F87D5B15  mov         rcx,qword ptr [blockA] 
00007FF6F87D5B1D  shl         r13,5 
00007FF6F87D5B21  imul        rax,qword ptr [strideA] 
00007FF6F87D5B26  mov         qword ptr [rbp+18h],r13 
00007FF6F87D5B2A  lea         r11,[rcx+rax*8] 
00007FF6F87D5B2E  mov         qword ptr [rbp],r11 
      {
        // loops on each largest micro vertical panel of rhs (depth * nr)
        for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D5B32  test        rbx,rbx 
00007FF6F87D5B35  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+122Ah (07FF6F87D5EAAh) 
00007FF6F87D5B3B  mov         rax,qword ptr [strideB] 
00007FF6F87D5B3F  mov         r13d,2 
00007FF6F87D5B45  mov         r9,qword ptr [offsetB] 
00007FF6F87D5B4D  shl         rax,5 
00007FF6F87D5B51  shl         r9,5 
00007FF6F87D5B55  add         r9,qword ptr [blockB] 
00007FF6F87D5B5D  vmovaps     xmm1,xmm13 
00007FF6F87D5B62  mov         qword ptr [i1],r9 
00007FF6F87D5B66  vxorps      ymm11,ymm0,ymm0 
00007FF6F87D5B6A  vbroadcastsd ymm12,xmm1 
00007FF6F87D5B6F  mov         qword ptr [rbp+40h],rax 
00007FF6F87D5B73  nop         dword ptr [rax] 
00007FF6F87D5B77  nop         word ptr [rax+rax] 
        {
          // We select a 1*Traits::LhsProgress x nr micro block of res which is entirely
          // stored into 1 x nr registers.
         
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(1*Traits::LhsProgress)];
00007FF6F87D5B80  mov         rcx,r11 
          prefetch(&blA[0]);
00007FF6F87D5B83  prefetcht0  [r11] 

          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
00007FF6F87D5B87  mov         rax,qword ptr [r14+8] 
00007FF6F87D5B8B  lea         r11,[r13-2] 
00007FF6F87D5B8F  mov         rdx,qword ptr [r14] 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D5B92  lea         rbx,[r13-1] 

          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
00007FF6F87D5B96  imul        r11,rax 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D5B9A  imul        rbx,rax 
          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
00007FF6F87D5B9E  mov         rdi,rax 
          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
00007FF6F87D5BA1  lea         r15,[r13+1] 
          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
00007FF6F87D5BA5  imul        rdi,r13 
          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
00007FF6F87D5BA9  imul        r15,rax 

          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
00007FF6F87D5BAD  add         r11,r12 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D5BB0  add         rbx,r12 
          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
00007FF6F87D5BB3  add         rdi,r12 

          // gets res block as register
          AccPacket C0, C1, C2, C3;
          traits.initAcc(C0);
00007FF6F87D5BB6  vmovupd     ymm7,ymm11 
          traits.initAcc(C1);
00007FF6F87D5BBB  vmovupd     ymm8,ymm11 
          traits.initAcc(C2);
00007FF6F87D5BC0  vmovupd     ymm9,ymm11 
          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
00007FF6F87D5BC5  add         r15,r12 
          traits.initAcc(C3);
00007FF6F87D5BC8  vmovupd     ymm10,ymm11 

          r0.prefetch(prefetch_res_offset);
00007FF6F87D5BCD  prefetcht0  [rdx+r11*8+20h] 
          r1.prefetch(prefetch_res_offset);
00007FF6F87D5BD3  prefetcht0  [rdx+rbx*8+20h] 
          r2.prefetch(prefetch_res_offset);
00007FF6F87D5BD8  prefetcht0  [rdx+rdi*8+20h] 
          r3.prefetch(prefetch_res_offset);
00007FF6F87D5BDD  prefetcht0  [rdx+r15*8+20h] 

          // performs "inner" products
          const RhsScalar* blB = &blockB[j2*strideB+offsetB*nr];
00007FF6F87D5BE3  mov         r10,r9 
          prefetch(&blB[0]);
00007FF6F87D5BE6  prefetcht0  [r9] 
          LhsPacket A0;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D5BEA  test        r8,r8 
00007FF6F87D5BED  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1170h (07FF6F87D5DF0h) 
        {
          // We select a 1*Traits::LhsProgress x nr micro block of res which is entirely
          // stored into 1 x nr registers.
         
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(1*Traits::LhsProgress)];
00007FF6F87D5BF3  lea         rax,[r9+30h] 
00007FF6F87D5BF7  lea         r9,[r8-1] 
00007FF6F87D5BFB  shr         r9,3 
00007FF6F87D5BFF  inc         r9 
00007FF6F87D5C02  nop         dword ptr [rax] 
00007FF6F87D5C06  nop         word ptr [rax+rax] 
          {
            EIGEN_ASM_COMMENT("begin gebp micro kernel 1pX4");
            RhsPacket B_0, B1, B2, B3;
               
#define EIGEN_GEBGP_ONESTEP(K) \
            do {                                                                \
              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 1pX4");        \
              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
              traits.loadLhs(&blA[(0+1*K)*LhsProgress], A0);                    \
              traits.broadcastRhs(&blB[(0+4*K)*RhsProgress], B_0, B1, B2, B3);  \
              traits.madd(A0, B_0, C0, B_0);                                    \
              traits.madd(A0, B1,  C1, B1);                                     \
              traits.madd(A0, B2,  C2, B2);                                     \
              traits.madd(A0, B3,  C3, B3);                                     \
              EIGEN_ASM_COMMENT("end step of gebp micro kernel 1pX4");          \
            } while(false)
           
            internal::prefetch(blB+(48+0));
00007FF6F87D5C10  prefetcht0  [rax+150h] 
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5C17  vmovupd     ymm6,ymmword ptr [rcx] 
00007FF6F87D5C1B  vbroadcastsd ymm2,mmword ptr [r10] 
00007FF6F87D5C20  vbroadcastsd ymm3,mmword ptr [rax-28h] 
00007FF6F87D5C26  vbroadcastsd ymm0,mmword ptr [rax-20h] 
00007FF6F87D5C2C  vbroadcastsd ymm1,mmword ptr [rax-18h] 
00007FF6F87D5C32  vfmadd231pd ymm7,ymm6,ymm2 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D5C37  vbroadcastsd ymm2,mmword ptr [rax-10h] 
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5C3D  vfmadd231pd ymm8,ymm6,ymm3 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D5C42  vbroadcastsd ymm3,mmword ptr [rax-8] 
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5C48  vfmadd231pd ymm9,ymm6,ymm0 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D5C4D  vbroadcastsd ymm0,mmword ptr [rax] 
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5C52  vfmadd231pd ymm10,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D5C57  vmovupd     ymm6,ymmword ptr [rcx+20h] 
00007FF6F87D5C5C  vbroadcastsd ymm1,mmword ptr [rax+8] 
00007FF6F87D5C62  vfmadd231pd ymm7,ymm6,ymm2 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D5C67  vbroadcastsd ymm2,mmword ptr [rax+10h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D5C6D  vfmadd231pd ymm8,ymm6,ymm3 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D5C72  vbroadcastsd ymm3,mmword ptr [rax+18h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D5C78  vfmadd231pd ymm9,ymm6,ymm0 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D5C7D  vbroadcastsd ymm0,mmword ptr [rax+20h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D5C83  vfmadd231pd ymm10,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D5C88  vmovupd     ymm6,ymmword ptr [rcx+40h] 
00007FF6F87D5C8D  vbroadcastsd ymm1,mmword ptr [rax+28h] 
00007FF6F87D5C93  vfmadd231pd ymm7,ymm6,ymm2 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D5C98  vbroadcastsd ymm2,mmword ptr [rax+30h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D5C9E  vfmadd231pd ymm8,ymm6,ymm3 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D5CA3  vbroadcastsd ymm3,mmword ptr [rax+38h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D5CA9  vfmadd231pd ymm9,ymm6,ymm0 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D5CAE  vbroadcastsd ymm0,mmword ptr [rax+40h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D5CB4  vfmadd231pd ymm10,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D5CB9  vmovupd     ymm6,ymmword ptr [rcx+60h] 
00007FF6F87D5CBE  vbroadcastsd ymm1,mmword ptr [rax+48h] 
00007FF6F87D5CC4  vfmadd231pd ymm7,ymm6,ymm2 
00007FF6F87D5CC9  vfmadd231pd ymm8,ymm6,ymm3 
00007FF6F87D5CCE  vfmadd231pd ymm9,ymm6,ymm0 
00007FF6F87D5CD3  vfmadd231pd ymm10,ymm6,ymm1 
            internal::prefetch(blB+(48+16));
00007FF6F87D5CD8  prefetcht0  [rax+1D0h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D5CDF  vmovupd     ymm6,ymmword ptr [rcx+80h] 
00007FF6F87D5CE7  vbroadcastsd ymm2,mmword ptr [rax+50h] 
00007FF6F87D5CED  vbroadcastsd ymm3,mmword ptr [rax+58h] 
00007FF6F87D5CF3  vbroadcastsd ymm0,mmword ptr [rax+60h] 
00007FF6F87D5CF9  vbroadcastsd ymm1,mmword ptr [rax+68h] 
00007FF6F87D5CFF  vfmadd231pd ymm7,ymm6,ymm2 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D5D04  vbroadcastsd ymm2,mmword ptr [rax+70h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D5D0A  vfmadd231pd ymm8,ymm6,ymm3 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D5D0F  vbroadcastsd ymm3,mmword ptr [rax+78h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D5D15  vfmadd231pd ymm9,ymm6,ymm0 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D5D1A  vbroadcastsd ymm0,mmword ptr [rax+80h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D5D23  vfmadd231pd ymm10,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D5D28  vmovupd     ymm6,ymmword ptr [rcx+0A0h] 
00007FF6F87D5D30  vbroadcastsd ymm1,mmword ptr [rax+88h] 
00007FF6F87D5D39  vfmadd231pd ymm7,ymm6,ymm2 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D5D3E  vbroadcastsd ymm2,mmword ptr [rax+90h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D5D47  vfmadd231pd ymm8,ymm6,ymm3 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D5D4C  vbroadcastsd ymm3,mmword ptr [rax+98h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D5D55  vfmadd231pd ymm9,ymm6,ymm0 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D5D5A  vbroadcastsd ymm0,mmword ptr [rax+0A0h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D5D63  vfmadd231pd ymm10,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D5D68  vmovupd     ymm6,ymmword ptr [rcx+0C0h] 
00007FF6F87D5D70  vbroadcastsd ymm1,mmword ptr [rax+0A8h] 
00007FF6F87D5D79  vfmadd231pd ymm7,ymm6,ymm2 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D5D7E  vbroadcastsd ymm2,mmword ptr [rax+0B0h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D5D87  vfmadd231pd ymm8,ymm6,ymm3 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D5D8C  vbroadcastsd ymm3,mmword ptr [rax+0B8h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D5D95  vfmadd231pd ymm9,ymm6,ymm0 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D5D9A  vbroadcastsd ymm0,mmword ptr [rax+0C0h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D5DA3  vfmadd231pd ymm10,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D5DA8  vmovupd     ymm6,ymmword ptr [rcx+0E0h] 
00007FF6F87D5DB0  vbroadcastsd ymm1,mmword ptr [rax+0C8h] 

            blB += pk*4*RhsProgress;
            blA += pk*1*LhsProgress;
00007FF6F87D5DB9  add         rcx,100h 
00007FF6F87D5DC0  lea         rax,[rax+100h] 
00007FF6F87D5DC7  add         r10,100h 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D5DCE  vfmadd231pd ymm7,ymm6,ymm2 
00007FF6F87D5DD3  vfmadd231pd ymm8,ymm6,ymm3 
00007FF6F87D5DD8  vfmadd231pd ymm9,ymm6,ymm0 
00007FF6F87D5DDD  vfmadd231pd ymm10,ymm6,ymm1 
          LhsPacket A0;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D5DE2  sub         r9,1 
00007FF6F87D5DE6  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0F90h (07FF6F87D5C10h) 
00007FF6F87D5DEC  mov         r9,qword ptr [rbp+10h] 

            EIGEN_ASM_COMMENT("end gebp micro kernel 1pX4");
          }
          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D5DF0  cmp         r8,rsi 
00007FF6F87D5DF3  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+11C1h (07FF6F87D5E41h) 
00007FF6F87D5DF5  mov         r9,rsi 
00007FF6F87D5DF8  lea         rax,[r10+10h] 
00007FF6F87D5DFC  sub         r9,r8 
00007FF6F87D5DFF  nop 
          {
            RhsPacket B_0, B1, B2, B3;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5E00  vmovupd     ymm6,ymmword ptr [rcx] 
            blB += 4*RhsProgress;
00007FF6F87D5E04  lea         rcx,[rcx+20h] 
          {
            RhsPacket B_0, B1, B2, B3;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5E08  vbroadcastsd ymm2,mmword ptr [rax-10h] 
00007FF6F87D5E0E  vbroadcastsd ymm3,mmword ptr [rax-8] 
00007FF6F87D5E14  vbroadcastsd ymm0,mmword ptr [rax] 
00007FF6F87D5E19  vbroadcastsd ymm1,mmword ptr [rax+8] 
            blB += 4*RhsProgress;
00007FF6F87D5E1F  lea         rax,[rax+20h] 
          {
            RhsPacket B_0, B1, B2, B3;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5E23  vfmadd231pd ymm7,ymm6,ymm2 
00007FF6F87D5E28  vfmadd231pd ymm8,ymm6,ymm3 
00007FF6F87D5E2D  vfmadd231pd ymm9,ymm6,ymm0 
00007FF6F87D5E32  vfmadd231pd ymm10,ymm6,ymm1 

            EIGEN_ASM_COMMENT("end gebp micro kernel 1pX4");
          }
          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D5E37  sub         r9,1 
00007FF6F87D5E3B  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1180h (07FF6F87D5E00h) 
00007FF6F87D5E3D  mov         r9,qword ptr [rbp+10h] 
            blA += 1*LhsProgress;
          }
#undef EIGEN_GEBGP_ONESTEP

          ResPacket R0, R1;
          ResPacket alphav = pset1<ResPacket>(alpha);

          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
00007FF6F87D5E41  vmovupd     ymm0,ymmword ptr [rdx+r11*8] 
          R1 = r1.loadPacket(0 * Traits::ResPacketSize);
00007FF6F87D5E47  vmovupd     ymm3,ymmword ptr [rdx+rbx*8] 
      {
        // loops on each largest micro vertical panel of rhs (depth * nr)
        for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D5E4C  add         r9,qword ptr [rbp+40h] 
00007FF6F87D5E50  add         r13,4 
          traits.acc(C1,  alphav, R1);
00007FF6F87D5E54  vfmadd231pd ymm3,ymm8,ymm12 
          traits.acc(C0, alphav, R0);
00007FF6F87D5E59  vfmadd231pd ymm0,ymm7,ymm12 
          r0.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D5E5E  vmovupd     ymmword ptr [rdx+r11*8],ymm0 
      {
        // loops on each largest micro vertical panel of rhs (depth * nr)
        for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D5E64  mov         r11,qword ptr [rbp] 
00007FF6F87D5E68  lea         rax,[r13-2] 
          r1.storePacket(0 * Traits::ResPacketSize, R1);
00007FF6F87D5E6C  vmovupd     ymmword ptr [rdx+rbx*8],ymm3 
          traits.acc(C2,  alphav, R0);
00007FF6F87D5E71  vmovupd     ymm1,ymmword ptr [rdx+rdi*8] 

          R0 = r2.loadPacket(0 * Traits::ResPacketSize);
          R1 = r3.loadPacket(0 * Traits::ResPacketSize);
00007FF6F87D5E76  vmovupd     ymm3,ymmword ptr [rdx+r15*8] 
      {
        // loops on each largest micro vertical panel of rhs (depth * nr)
        for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D5E7C  mov         rbx,qword ptr [j2] 
00007FF6F87D5E80  mov         qword ptr [rbp+10h],r9 
          traits.acc(C2,  alphav, R0);
00007FF6F87D5E84  vfmadd231pd ymm1,ymm9,ymm12 
00007FF6F87D5E89  vmovupd     ymm0,ymm1 
          traits.acc(C3,  alphav, R1);
00007FF6F87D5E8D  vfmadd231pd ymm3,ymm10,ymm12 
          r2.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D5E92  vmovupd     ymmword ptr [rdx+rdi*8],ymm0 
          r3.storePacket(0 * Traits::ResPacketSize, R1);
00007FF6F87D5E97  vmovupd     ymmword ptr [rdx+r15*8],ymm3 
      {
        // loops on each largest micro vertical panel of rhs (depth * nr)
        for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D5E9D  cmp         rax,rbx 
00007FF6F87D5EA0  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0F00h (07FF6F87D5B80h) 
00007FF6F87D5EA6  mov         r13,qword ptr [rbp+18h] 
        }

        // Deal with remaining columns of the rhs
        for(Index j2=packet_cols4; j2<cols; j2++)
00007FF6F87D5EAA  mov         r10,rbx 
00007FF6F87D5EAD  cmp         rbx,qword ptr [cols] 
00007FF6F87D5EB5  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1385h (07FF6F87D6005h) 
00007FF6F87D5EBB  mov         rcx,qword ptr [strideB] 
00007FF6F87D5EBF  mov         rax,rbx 
00007FF6F87D5EC2  mov         r13,qword ptr [cols] 
00007FF6F87D5ECA  imul        rax,rcx 
00007FF6F87D5ECE  lea         r15,[rcx*8] 
00007FF6F87D5ED6  mov         rcx,qword ptr [blockB] 
00007FF6F87D5EDE  add         rax,qword ptr [offsetB] 
00007FF6F87D5EE6  vmovaps     xmm1,xmm13 
00007FF6F87D5EEB  vxorps      ymm6,ymm0,ymm0 
00007FF6F87D5EEF  vbroadcastsd ymm5,xmm1 
00007FF6F87D5EF4  lea         rbx,[rcx+rax*8] 
00007FF6F87D5EF8  nop         dword ptr [rax+rax] 
        {
          // One column at a time
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(1*Traits::LhsProgress)];
00007FF6F87D5F00  mov         rax,r11 
          prefetch(&blA[0]);
00007FF6F87D5F03  prefetcht0  [r11] 

          LinearMapper r0 = res.getLinearMapper(i, j2);
00007FF6F87D5F07  mov         rdi,qword ptr [r14] 
00007FF6F87D5F0A  mov         r9,r10 
00007FF6F87D5F0D  imul        r9,qword ptr [r14+8] 

          // gets res block as register
          AccPacket C0;
          traits.initAcc(C0);
00007FF6F87D5F12  vmovupd     ymm3,ymm6 

          LinearMapper r0 = res.getLinearMapper(i, j2);
00007FF6F87D5F16  add         r9,r12 

          // performs "inner" products
          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
00007FF6F87D5F19  mov         rcx,rbx 
          LhsPacket A0;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D5F1C  test        r8,r8 
00007FF6F87D5F1F  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+132Ah (07FF6F87D5FAAh) 
        {
          // One column at a time
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(1*Traits::LhsProgress)];
00007FF6F87D5F25  lea         rdx,[r8-1] 
00007FF6F87D5F29  shr         rdx,3 
00007FF6F87D5F2D  inc         rdx 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D5F30  vbroadcastsd ymm2,mmword ptr [rcx+8] 
          {
            EIGEN_ASM_COMMENT("begin gebp micro kernel 1pX1");
            RhsPacket B_0;
       
#define EIGEN_GEBGP_ONESTEP(K) \
            do {                                                                \
              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 1pX1");        \
              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
              traits.loadLhs(&blA[(0+1*K)*LhsProgress], A0);                    \
              traits.loadRhs(&blB[(0+K)*RhsProgress], B_0);                     \
              traits.madd(A0, B_0, C0, B_0);                                    \
              EIGEN_ASM_COMMENT("end step of gebp micro kernel 1pX1");          \
            } while(false);

            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5F36  vbroadcastsd ymm1,mmword ptr [rcx] 
00007FF6F87D5F3B  vfmadd231pd ymm3,ymm1,ymmword ptr [rax] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D5F40  vfmadd231pd ymm3,ymm2,ymmword ptr [rax+20h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D5F46  vbroadcastsd ymm2,mmword ptr [rcx+10h] 
00007FF6F87D5F4C  vfmadd231pd ymm3,ymm2,ymmword ptr [rax+40h] 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D5F52  vbroadcastsd ymm2,mmword ptr [rcx+18h] 
00007FF6F87D5F58  vfmadd231pd ymm3,ymm2,ymmword ptr [rax+60h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D5F5E  vbroadcastsd ymm2,mmword ptr [rcx+20h] 
00007FF6F87D5F64  vfmadd231pd ymm3,ymm2,ymmword ptr [rax+80h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D5F6D  vbroadcastsd ymm2,mmword ptr [rcx+28h] 
00007FF6F87D5F73  vfmadd231pd ymm3,ymm2,ymmword ptr [rax+0A0h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D5F7C  vbroadcastsd ymm2,mmword ptr [rcx+30h] 
00007FF6F87D5F82  vfmadd231pd ymm3,ymm2,ymmword ptr [rax+0C0h] 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D5F8B  vbroadcastsd ymm2,mmword ptr [rcx+38h] 
00007FF6F87D5F91  vfmadd231pd ymm3,ymm2,ymmword ptr [rax+0E0h] 

            blB += pk*RhsProgress;
            blA += pk*1*Traits::LhsProgress;
00007FF6F87D5F9A  add         rax,100h 
00007FF6F87D5FA0  add         rcx,40h 
00007FF6F87D5FA4  sub         rdx,1 
00007FF6F87D5FA8  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+12B0h (07FF6F87D5F30h) 

            EIGEN_ASM_COMMENT("end gebp micro kernel 1pX1");
          }

          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D5FAA  cmp         r8,rsi 
00007FF6F87D5FAD  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1359h (07FF6F87D5FD9h) 
00007FF6F87D5FAF  mov         rdx,rsi 
00007FF6F87D5FB2  sub         rdx,r8 
00007FF6F87D5FB5  nop         word ptr [rax+rax] 
            blA += 1*Traits::LhsProgress;
00007FF6F87D5FC0  lea         rax,[rax+20h] 
          {
            RhsPacket B_0;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5FC4  vbroadcastsd ymm1,mmword ptr [rcx] 
            blB += RhsProgress;
00007FF6F87D5FC9  lea         rcx,[rcx+8] 
          {
            RhsPacket B_0;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D5FCD  vfmadd231pd ymm3,ymm1,ymmword ptr [rax-20h] 

            EIGEN_ASM_COMMENT("end gebp micro kernel 1pX1");
          }

          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D5FD3  sub         rdx,1 
00007FF6F87D5FD7  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1340h (07FF6F87D5FC0h) 
          }
#undef EIGEN_GEBGP_ONESTEP
          ResPacket R0;
          ResPacket alphav = pset1<ResPacket>(alpha);
          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
00007FF6F87D5FD9  vmovupd     ymm1,ymmword ptr [rdi+r9*8] 
          traits.acc(C0, alphav, R0);
00007FF6F87D5FDF  vfmadd231pd ymm1,ymm3,ymm5 
        }

        // Deal with remaining columns of the rhs
        for(Index j2=packet_cols4; j2<cols; j2++)
00007FF6F87D5FE4  inc         r10 
00007FF6F87D5FE7  add         rbx,r15 
          traits.acc(C0, alphav, R0);
00007FF6F87D5FEA  vmovupd     ymm2,ymm1 
          r0.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D5FEE  vmovupd     ymmword ptr [rdi+r9*8],ymm2 
        }

        // Deal with remaining columns of the rhs
        for(Index j2=packet_cols4; j2<cols; j2++)
00007FF6F87D5FF4  cmp         r10,r13 
00007FF6F87D5FF7  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1280h (07FF6F87D5F00h) 
00007FF6F87D5FFD  mov         r13,qword ptr [rbp+18h] 
00007FF6F87D6001  mov         rbx,qword ptr [j2] 
          }
        }
      }
    }
    //---------- Process 1 * LhsProgress rows at once ----------
    if(mr>=1*Traits::LhsProgress)
    {
      // loops on each largest micro horizontal panel of lhs (1*LhsProgress x depth)
      for(Index i=peeled_mc2; i<peeled_mc1; i+=1*LhsProgress)
00007FF6F87D6005  add         r11,r13 
00007FF6F87D6008  add         r12,4 
00007FF6F87D600C  mov         qword ptr [rbp],r11 
00007FF6F87D6010  cmp         r12,qword ptr [peeled_mc1] 
00007FF6F87D6014  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0EB2h (07FF6F87D5B32h) 
        }
      }
    }
    //---------- Process remaining rows, 1 at once ----------
    if(peeled_mc1<rows)
00007FF6F87D601A  mov         r8,qword ptr [peeled_mc1] 
00007FF6F87D601E  cmp         r8,qword ptr [rows] 
00007FF6F87D6026  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1796h (07FF6F87D6416h) 
    {
      // loop on each panel of the rhs
      for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D602C  mov         r12,qword ptr [strideA] 
00007FF6F87D6030  xor         edi,edi 
00007FF6F87D6032  test        rbx,rbx 
00007FF6F87D6035  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+159Bh (07FF6F87D621Bh) 
00007FF6F87D603B  mov         r13,qword ptr [strideB] 
00007FF6F87D603F  lea         r15,[r12*8] 
00007FF6F87D6047  mov         rbx,qword ptr [offsetB] 
00007FF6F87D604F  mov         rcx,r8 
00007FF6F87D6052  imul        rcx,r12 
00007FF6F87D6056  vxorps      ymm0,ymm0,ymm0 
00007FF6F87D605A  shl         r13,5 
00007FF6F87D605E  mov         rax,rsi 
00007FF6F87D6061  cqo 
00007FF6F87D6063  shl         rbx,5 
00007FF6F87D6067  and         edx,3 
00007FF6F87D606A  mov         qword ptr [rbp+40h],r13 
00007FF6F87D606E  vmovupd     ymm10,ymm0 
00007FF6F87D6072  vmovaps     xmm0,xmm13 
00007FF6F87D6077  vbroadcastsd ymm11,xmm0 
00007FF6F87D607C  lea         r11,[rdx+rax] 
00007FF6F87D6080  mov         rax,qword ptr [blockA] 
00007FF6F87D6088  and         r11,0FFFFFFFFFFFFFFFCh 
00007FF6F87D608C  add         rbx,qword ptr [blockB] 
00007FF6F87D6094  lea         r12,[rax+rcx*8] 
00007FF6F87D6098  nop         dword ptr [rax+rax] 
      {
        // loop on each row of the lhs (1*LhsProgress x depth)
        for(Index i=peeled_mc1; i<rows; i+=1)
00007FF6F87D60A0  mov         r13,qword ptr [rows] 
00007FF6F87D60A8  mov         r10,r8 
00007FF6F87D60AB  mov         r9,r12 
00007FF6F87D60AE  xchg        ax,ax 
        {
          const LhsScalar* blA = &blockA[i*strideA+offsetA];
00007FF6F87D60B0  mov         rax,r9 
          prefetch(&blA[0]);
00007FF6F87D60B3  prefetcht0  [r9] 

            const Index spk   = (std::max)(1,SwappedTraits::LhsProgress/4);
00007FF6F87D60B7  xor         r8d,r8d 
00007FF6F87D60BA  mov         dword ptr [rbp+0E8h],1 
00007FF6F87D60C4  mov         dword ptr [rbp+0ECh],1 
00007FF6F87D60CE  mov         rcx,rbx 
          const RhsScalar* blB = &blockB[j2*strideB+offsetB*nr];

          if( (SwappedTraits::LhsProgress % 4)==0 )
          {
            // NOTE The following piece of code wont work for 512 bit registers
            SAccPacket C0, C1, C2, C3;
            straits.initAcc(C0);
00007FF6F87D60D1  vmovupd     ymm6,ymm10 
            straits.initAcc(C1);
00007FF6F87D60D6  vmovupd     ymm7,ymm10 
            straits.initAcc(C2);
00007FF6F87D60DB  vmovupd     ymm8,ymm10 
            straits.initAcc(C3);
00007FF6F87D60E0  vmovupd     ymm9,ymm10 
            const Index endk  = (depth/spk)*spk;
            const Index endk4 = (depth/(spk*4))*(spk*4);

            Index k=0;
            for(; k<endk4; k+=4*spk)
00007FF6F87D60E5  test        r11,r11 
00007FF6F87D60E8  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+14BCh (07FF6F87D613Ch) 
        {
          const LhsScalar* blA = &blockA[i*strideA+offsetA];
00007FF6F87D60EA  lea         rdx,[r11-1] 
00007FF6F87D60EE  shr         rdx,2 
00007FF6F87D60F2  inc         rdx 
            const Index endk  = (depth/spk)*spk;
            const Index endk4 = (depth/(spk*4))*(spk*4);

            Index k=0;
            for(; k<endk4; k+=4*spk)
00007FF6F87D60F5  lea         r8,[rdx*4] 
00007FF6F87D60FD  nop         dword ptr [rax] 
            {
              SLhsPacket A0,A1;
              SRhsPacket B_0,B_1;

              straits.loadLhsUnaligned(blB+0*SwappedTraits::LhsProgress, A0);
              straits.loadLhsUnaligned(blB+1*SwappedTraits::LhsProgress, A1);

              straits.loadRhsQuad(blA+0*spk, B_0);
00007FF6F87D6100  vbroadcastsd ymm0,mmword ptr [rax] 
              straits.loadRhsQuad(blA+1*spk, B_1);
00007FF6F87D6105  vbroadcastsd ymm1,mmword ptr [rax+8] 
              straits.madd(A0,B_0,C0,B_0);
00007FF6F87D610B  vfmadd231pd ymm6,ymm0,ymmword ptr [rcx] 
              straits.madd(A1,B_1,C1,B_1);
00007FF6F87D6110  vfmadd231pd ymm7,ymm1,ymmword ptr [rcx+20h] 

              straits.loadLhsUnaligned(blB+2*SwappedTraits::LhsProgress, A0);
              straits.loadLhsUnaligned(blB+3*SwappedTraits::LhsProgress, A1);
              straits.loadRhsQuad(blA+2*spk, B_0);
00007FF6F87D6116  vbroadcastsd ymm1,mmword ptr [rax+10h] 
              straits.loadRhsQuad(blA+3*spk, B_1);
00007FF6F87D611C  vbroadcastsd ymm0,mmword ptr [rax+18h] 
              straits.madd(A0,B_0,C2,B_0);
00007FF6F87D6122  vfmadd231pd ymm8,ymm1,ymmword ptr [rcx+40h] 
              straits.madd(A1,B_1,C3,B_1);
00007FF6F87D6128  vfmadd231pd ymm9,ymm0,ymmword ptr [rcx+60h] 

              blB += 4*SwappedTraits::LhsProgress;
00007FF6F87D612E  sub         rcx,0FFFFFFFFFFFFFF80h 
              blA += 4*spk;
00007FF6F87D6132  add         rax,20h 
00007FF6F87D6136  sub         rdx,1 
00007FF6F87D613A  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1480h (07FF6F87D6100h) 
            }
            C0 = padd(padd(C0,C1),padd(C2,C3));
00007FF6F87D613C  vaddpd      ymm1,ymm7,ymm6 
00007FF6F87D6140  vaddpd      ymm0,ymm9,ymm8 
00007FF6F87D6145  vaddpd      ymm4,ymm0,ymm1 
            for(; k<endk; k+=spk)
00007FF6F87D6149  cmp         r8,rsi 
00007FF6F87D614C  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+14F9h (07FF6F87D6179h) 
            }
            C0 = padd(padd(C0,C1),padd(C2,C3));
00007FF6F87D614E  mov         rdx,rsi 
00007FF6F87D6151  sub         rdx,r8 
00007FF6F87D6154  nop         dword ptr [rax] 
00007FF6F87D6158  nop         dword ptr [rax+rax] 

              blB += SwappedTraits::LhsProgress;
00007FF6F87D6160  lea         rcx,[rcx+20h] 
            {
              SLhsPacket A0;
              SRhsPacket B_0;

              straits.loadLhsUnaligned(blB, A0);
              straits.loadRhsQuad(blA, B_0);
00007FF6F87D6164  vbroadcastsd ymm1,mmword ptr [rax] 
              blA += spk;
00007FF6F87D6169  lea         rax,[rax+8] 
              straits.madd(A0,B_0,C0,B_0);
00007FF6F87D616D  vfmadd231pd ymm4,ymm1,ymmword ptr [rcx-20h] 
            for(; k<endk; k+=spk)
00007FF6F87D6173  sub         rdx,1 
00007FF6F87D6177  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+14E0h (07FF6F87D6160h) 
            }
            if(SwappedTraits::LhsProgress==8)
            {
              // Special case where we have to first reduce the accumulation register C0
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SResPacket>::half,SResPacket>::type SResPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SLhsPacket>::half,SLhsPacket>::type SLhsPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SLhsPacket>::half,SRhsPacket>::type SRhsPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SAccPacket>::half,SAccPacket>::type SAccPacketHalf;

              SResPacketHalf R = res.template gatherPacket<SResPacketHalf>(i, j2);
              SResPacketHalf alphav = pset1<SResPacketHalf>(alpha);

              if(depth-endk>0)
              {
                // We have to handle the last row of the rhs which corresponds to a half-packet
                SLhsPacketHalf a0;
                SRhsPacketHalf b0;
                straits.loadLhsUnaligned(blB, a0);
                straits.loadRhs(blA, b0);
                SAccPacketHalf c0 = predux4(C0);
                straits.madd(a0,b0,c0,b0);
                straits.acc(c0, alphav, R);
              }
              else
              {
                straits.acc(predux4(C0), alphav, R);
              }
              res.scatterPacket(i, j2, R);
            }
            else
            {
              SResPacket R = res.template gatherPacket<SResPacket>(i, j2);
00007FF6F87D6179  mov         r8,qword ptr [r14+8] 
00007FF6F87D617D  mov         rcx,rdi 
00007FF6F87D6180  mov         rax,qword ptr [r14] 
      {
        // loop on each row of the lhs (1*LhsProgress x depth)
        for(Index i=peeled_mc1; i<rows; i+=1)
00007FF6F87D6183  add         r9,r15 
            }
            if(SwappedTraits::LhsProgress==8)
            {
              // Special case where we have to first reduce the accumulation register C0
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SResPacket>::half,SResPacket>::type SResPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SLhsPacket>::half,SLhsPacket>::type SLhsPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SLhsPacket>::half,SRhsPacket>::type SRhsPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SAccPacket>::half,SAccPacket>::type SAccPacketHalf;

              SResPacketHalf R = res.template gatherPacket<SResPacketHalf>(i, j2);
              SResPacketHalf alphav = pset1<SResPacketHalf>(alpha);

              if(depth-endk>0)
              {
                // We have to handle the last row of the rhs which corresponds to a half-packet
                SLhsPacketHalf a0;
                SRhsPacketHalf b0;
                straits.loadLhsUnaligned(blB, a0);
                straits.loadRhs(blA, b0);
                SAccPacketHalf c0 = predux4(C0);
                straits.madd(a0,b0,c0,b0);
                straits.acc(c0, alphav, R);
              }
              else
              {
                straits.acc(predux4(C0), alphav, R);
              }
              res.scatterPacket(i, j2, R);
            }
            else
            {
              SResPacket R = res.template gatherPacket<SResPacket>(i, j2);
00007FF6F87D6186  imul        rcx,r8 
00007FF6F87D618A  add         rcx,r10 
      {
        // loop on each row of the lhs (1*LhsProgress x depth)
        for(Index i=peeled_mc1; i<rows; i+=1)
00007FF6F87D618D  inc         r10 
            }
            if(SwappedTraits::LhsProgress==8)
            {
              // Special case where we have to first reduce the accumulation register C0
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SResPacket>::half,SResPacket>::type SResPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SLhsPacket>::half,SLhsPacket>::type SLhsPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SLhsPacket>::half,SRhsPacket>::type SRhsPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SAccPacket>::half,SAccPacket>::type SAccPacketHalf;

              SResPacketHalf R = res.template gatherPacket<SResPacketHalf>(i, j2);
              SResPacketHalf alphav = pset1<SResPacketHalf>(alpha);

              if(depth-endk>0)
              {
                // We have to handle the last row of the rhs which corresponds to a half-packet
                SLhsPacketHalf a0;
                SRhsPacketHalf b0;
                straits.loadLhsUnaligned(blB, a0);
                straits.loadRhs(blA, b0);
                SAccPacketHalf c0 = predux4(C0);
                straits.madd(a0,b0,c0,b0);
                straits.acc(c0, alphav, R);
              }
              else
              {
                straits.acc(predux4(C0), alphav, R);
              }
              res.scatterPacket(i, j2, R);
            }
            else
            {
              SResPacket R = res.template gatherPacket<SResPacket>(i, j2);
00007FF6F87D6190  vmovsd      xmm1,qword ptr [rax+rcx*8] 
00007FF6F87D6195  lea         rdx,[rax+rcx*8] 
00007FF6F87D6199  mov         rcx,r8 
00007FF6F87D619C  vmovsd      xmm0,qword ptr [rdx+r8*8] 
00007FF6F87D61A2  vunpcklpd   xmm1,xmm1,xmm0 
00007FF6F87D61A6  add         rcx,rcx 
00007FF6F87D61A9  lea         rax,[r8+r8*2] 
00007FF6F87D61AD  vmovsd      xmm2,qword ptr [rdx+rax*8] 
              res.scatterPacket(i, j2, R);
00007FF6F87D61B2  mov         rax,r8 
00007FF6F87D61B5  add         rax,rax 
            }
            if(SwappedTraits::LhsProgress==8)
            {
              // Special case where we have to first reduce the accumulation register C0
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SResPacket>::half,SResPacket>::type SResPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SLhsPacket>::half,SLhsPacket>::type SLhsPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SLhsPacket>::half,SRhsPacket>::type SRhsPacketHalf;
              typedef typename conditional<SwappedTraits::LhsProgress==8,typename unpacket_traits<SAccPacket>::half,SAccPacket>::type SAccPacketHalf;

              SResPacketHalf R = res.template gatherPacket<SResPacketHalf>(i, j2);
              SResPacketHalf alphav = pset1<SResPacketHalf>(alpha);

              if(depth-endk>0)
              {
                // We have to handle the last row of the rhs which corresponds to a half-packet
                SLhsPacketHalf a0;
                SRhsPacketHalf b0;
                straits.loadLhsUnaligned(blB, a0);
                straits.loadRhs(blA, b0);
                SAccPacketHalf c0 = predux4(C0);
                straits.madd(a0,b0,c0,b0);
                straits.acc(c0, alphav, R);
              }
              else
              {
                straits.acc(predux4(C0), alphav, R);
              }
              res.scatterPacket(i, j2, R);
            }
            else
            {
              SResPacket R = res.template gatherPacket<SResPacket>(i, j2);
00007FF6F87D61B8  vmovsd      xmm3,qword ptr [rdx+rcx*8] 
00007FF6F87D61BD  vunpcklpd   xmm3,xmm3,xmm2 
00007FF6F87D61C1  vinsertf128 ymm1,ymm1,xmm3,1 
              SResPacket alphav = pset1<SResPacket>(alpha);
              straits.acc(C0, alphav, R);
00007FF6F87D61C7  vfmadd231pd ymm1,ymm4,ymm11 
00007FF6F87D61CC  vmovupd     ymm2,ymm1 
              res.scatterPacket(i, j2, R);
00007FF6F87D61D0  vextractf128 xmm1,ymm1,0 
              res.scatterPacket(i, j2, R);
00007FF6F87D61D6  vmovsd      qword ptr [rdx],xmm1 
00007FF6F87D61DA  vmovhpd     qword ptr [rdx+r8*8],xmm1 
00007FF6F87D61E0  vextractf128 xmm1,ymm2,1 
00007FF6F87D61E6  vmovsd      qword ptr [rdx+rax*8],xmm1 
00007FF6F87D61EB  lea         rax,[r8+r8*2] 
00007FF6F87D61EF  vmovhpd     qword ptr [rdx+rax*8],xmm1 
      {
        // loop on each row of the lhs (1*LhsProgress x depth)
        for(Index i=peeled_mc1; i<rows; i+=1)
00007FF6F87D61F4  cmp         r10,r13 
00007FF6F87D61F7  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1430h (07FF6F87D60B0h) 
    {
      // loop on each panel of the rhs
      for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D61FD  add         rbx,qword ptr [rbp+40h] 
00007FF6F87D6201  add         rdi,4 
00007FF6F87D6205  mov         r8,qword ptr [peeled_mc1] 
00007FF6F87D6209  cmp         rdi,qword ptr [j2] 
00007FF6F87D620D  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1420h (07FF6F87D60A0h) 
00007FF6F87D6213  mov         r12,qword ptr [strideA] 
00007FF6F87D6217  mov         rbx,qword ptr [j2] 
            }
          }
          else // scalar path
          {
            // get a 1 x 4 res block as registers
            ResScalar C0(0), C1(0), C2(0), C3(0);

            for(Index k=0; k<depth; k++)
            {
              LhsScalar A0;
              RhsScalar B_0, B_1;

              A0 = blA[k];

              B_0 = blB[0];
              B_1 = blB[1];
              CJMADD(cj,A0,B_0,C0,  B_0);
              CJMADD(cj,A0,B_1,C1,  B_1);
             
              B_0 = blB[2];
              B_1 = blB[3];
              CJMADD(cj,A0,B_0,C2,  B_0);
              CJMADD(cj,A0,B_1,C3,  B_1);
             
              blB += 4;
            }
            res(i, j2 + 0) += alpha * C0;
            res(i, j2 + 1) += alpha * C1;
            res(i, j2 + 2) += alpha * C2;
            res(i, j2 + 3) += alpha * C3;
          }
        }
      }
      // remaining columns
      for(Index j2=packet_cols4; j2<cols; j2++)
00007FF6F87D621B  mov         r13,qword ptr [cols] 
00007FF6F87D6223  cmp         rbx,r13 
00007FF6F87D6226  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1796h (07FF6F87D6416h) 
00007FF6F87D622C  mov         rcx,qword ptr [blockA] 
00007FF6F87D6234  lea         rbx,[r12*8] 
00007FF6F87D623C  mov         rax,r8 
00007FF6F87D623F  imul        rax,r12 
00007FF6F87D6243  mov         r12,qword ptr [j2] 
00007FF6F87D6247  vxorps      xmm5,xmm5,xmm5 
00007FF6F87D624B  lea         r15,[rcx+rax*8] 
00007FF6F87D624F  mov         rcx,qword ptr [strideB] 
00007FF6F87D6253  mov         rax,r12 
00007FF6F87D6256  imul        rax,rcx 
00007FF6F87D625A  lea         rdi,[rcx*8] 
00007FF6F87D6262  mov         rcx,qword ptr [blockB] 
00007FF6F87D626A  add         rax,qword ptr [offsetB] 
00007FF6F87D6272  lea         r9,[rcx+rax*8] 
00007FF6F87D6276  nop         word ptr [rax+rax] 
      {
        // loop on each row of the lhs (1*LhsProgress x depth)
        for(Index i=peeled_mc1; i<rows; i+=1)
00007FF6F87D6280  mov         r11,r8 
00007FF6F87D6283  mov         r10,r15 
00007FF6F87D6286  nop         word ptr [rax+rax] 
        {
          const LhsScalar* blA = &blockA[i*strideA+offsetA];
          prefetch(&blA[0]);
00007FF6F87D6290  prefetcht0  [r10] 
          // gets a 1 x 1 res block as registers
          ResScalar C0(0);
00007FF6F87D6294  xor         ecx,ecx 
00007FF6F87D6296  vmovaps     xmm3,xmm5 
          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
          for(Index k=0; k<depth; k++)
00007FF6F87D629A  test        rsi,rsi 
00007FF6F87D629D  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1751h (07FF6F87D63D1h) 
00007FF6F87D62A3  cmp         rsi,8 
00007FF6F87D62A7  jb          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+16A3h (07FF6F87D6323h) 
00007FF6F87D62A9  mov         rax,rsi 
00007FF6F87D62AC  mov         r8,rsi 
00007FF6F87D62AF  cqo 
00007FF6F87D62B1  and         edx,7 
00007FF6F87D62B4  add         rax,rdx 
00007FF6F87D62B7  and         eax,7 
00007FF6F87D62BA  sub         rax,rdx 
00007FF6F87D62BD  mov         rdx,r10 
00007FF6F87D62C0  sub         r8,rax 
00007FF6F87D62C3  lea         rax,[r9+20h] 
00007FF6F87D62C7  vxorps      ymm3,ymm0,ymm0 
00007FF6F87D62CB  sub         rdx,r9 
00007FF6F87D62CE  vmovupd     ymm4,ymm3 
00007FF6F87D62D2  nop         dword ptr [rax] 
00007FF6F87D62D6  nop         word ptr [rax+rax] 
            RhsScalar B_0 = blB[k];
00007FF6F87D62E0  vmovupd     ymm0,ymmword ptr [rax-20h] 
            CJMADD(cj, A0, B_0, C0, B_0);
00007FF6F87D62E5  vmulpd      ymm1,ymm0,ymmword ptr [rax+rdx-20h] 
            RhsScalar B_0 = blB[k];
00007FF6F87D62EB  vmovupd     ymm0,ymmword ptr [rax] 
00007FF6F87D62EF  vaddpd      ymm3,ymm1,ymm3 
            CJMADD(cj, A0, B_0, C0, B_0);
00007FF6F87D62F3  vmulpd      ymm1,ymm0,ymmword ptr [rax+rdx] 
          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
          for(Index k=0; k<depth; k++)
00007FF6F87D62F8  add         rcx,8 
00007FF6F87D62FC  lea         rax,[rax+40h] 
00007FF6F87D6300  vaddpd      ymm2,ymm1,ymm4 
00007FF6F87D6304  vmovupd     ymm4,ymm2 
00007FF6F87D6308  cmp         rcx,r8 
00007FF6F87D630B  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1660h (07FF6F87D62E0h) 
00007FF6F87D630D  vaddpd      ymm0,ymm3,ymm2 
00007FF6F87D6311  vhaddpd     ymm2,ymm0,ymm0 
00007FF6F87D6315  vmovupd     ymm0,ymm2 
00007FF6F87D6319  vextractf128 xmm4,ymm2,1 
00007FF6F87D631F  vaddpd      xmm3,xmm4,xmm0 
00007FF6F87D6323  cmp         rcx,rsi 
00007FF6F87D6326  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1751h (07FF6F87D63D1h) 
00007FF6F87D632C  mov         rax,rsi 
00007FF6F87D632F  sub         rax,rcx 
00007FF6F87D6332  cmp         rax,4 
00007FF6F87D6336  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1724h (07FF6F87D63A4h) 
00007FF6F87D6338  lea         rax,[rcx+1] 
00007FF6F87D633C  mov         r8,rsi 
00007FF6F87D633F  sub         r8,rcx 
00007FF6F87D6342  lea         rax,[r9+rax*8] 
00007FF6F87D6346  sub         r8,4 
00007FF6F87D634A  mov         rdx,r10 
00007FF6F87D634D  shr         r8,2 
00007FF6F87D6351  sub         rdx,r9 
00007FF6F87D6354  inc         r8 
00007FF6F87D6357  lea         rcx,[rcx+r8*4] 
00007FF6F87D635B  nop         dword ptr [rax+rax] 
          {
            LhsScalar A0 = blA[k];
00007FF6F87D6360  vmovsd      xmm0,qword ptr [rax+rdx-8] 
            CJMADD(cj, A0, B_0, C0, B_0);
00007FF6F87D6366  vmulsd      xmm0,xmm0,mmword ptr [rax-8] 
          {
            LhsScalar A0 = blA[k];
00007FF6F87D636B  vmovsd      xmm1,qword ptr [rax+rdx] 
            CJMADD(cj, A0, B_0, C0, B_0);
00007FF6F87D6370  vmulsd      xmm2,xmm1,mmword ptr [rax] 
          {
            LhsScalar A0 = blA[k];
00007FF6F87D6374  vmovsd      xmm1,qword ptr [rax+rdx+10h] 
            CJMADD(cj, A0, B_0, C0, B_0);
00007FF6F87D637A  lea         rax,[rax+20h] 
00007FF6F87D637E  vaddsd      xmm3,xmm3,xmm0 
          {
            LhsScalar A0 = blA[k];
00007FF6F87D6382  vmovsd      xmm0,qword ptr [rax+rdx-18h] 
            CJMADD(cj, A0, B_0, C0, B_0);
00007FF6F87D6388  vmulsd      xmm0,xmm0,mmword ptr [rax-18h] 
00007FF6F87D638D  vaddsd      xmm4,xmm3,xmm2 
00007FF6F87D6391  vaddsd      xmm2,xmm4,xmm0 
00007FF6F87D6395  vmulsd      xmm0,xmm1,mmword ptr [rax-10h] 
00007FF6F87D639A  vaddsd      xmm3,xmm2,xmm0 
00007FF6F87D639E  sub         r8,1 
00007FF6F87D63A2  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+16E0h (07FF6F87D6360h) 
          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
          for(Index k=0; k<depth; k++)
00007FF6F87D63A4  cmp         rcx,rsi 
00007FF6F87D63A7  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1751h (07FF6F87D63D1h) 
00007FF6F87D63A9  mov         r8,r10 
00007FF6F87D63AC  lea         rax,[r9+rcx*8] 
00007FF6F87D63B0  sub         r8,r9 
00007FF6F87D63B3  mov         rdx,rsi 
00007FF6F87D63B6  sub         rdx,rcx 
            CJMADD(cj, A0, B_0, C0, B_0);
00007FF6F87D63B9  vmovsd      xmm1,qword ptr [rax] 
00007FF6F87D63BD  vfmadd132sd xmm1,xmm3,mmword ptr [rax+r8] 
00007FF6F87D63C3  lea         rax,[rax+8] 
00007FF6F87D63C7  vmovapd     xmm3,xmm1 
          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
          for(Index k=0; k<depth; k++)
00007FF6F87D63CB  sub         rdx,1 
00007FF6F87D63CF  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1739h (07FF6F87D63B9h) 
          }
          res(i, j2) += alpha * C0;
00007FF6F87D63D1  mov         rax,qword ptr [r14] 
00007FF6F87D63D4  mov         rcx,r12 
00007FF6F87D63D7  imul        rcx,qword ptr [r14+8] 
00007FF6F87D63DC  vmovaps     xmm0,xmm13 
00007FF6F87D63E1  add         rcx,r11 
      {
        // loop on each row of the lhs (1*LhsProgress x depth)
        for(Index i=peeled_mc1; i<rows; i+=1)
00007FF6F87D63E4  add         r10,rbx 
00007FF6F87D63E7  inc         r11 
          }
          res(i, j2) += alpha * C0;
00007FF6F87D63EA  vfmadd213sd xmm0,xmm3,mmword ptr [rax+rcx*8] 
00007FF6F87D63F0  vmovsd      qword ptr [rax+rcx*8],xmm0 
00007FF6F87D63F5  cmp         r11,qword ptr [rows] 
00007FF6F87D63FD  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1610h (07FF6F87D6290h) 
            }
          }
          else // scalar path
          {
            // get a 1 x 4 res block as registers
            ResScalar C0(0), C1(0), C2(0), C3(0);

            for(Index k=0; k<depth; k++)
            {
              LhsScalar A0;
              RhsScalar B_0, B_1;

              A0 = blA[k];

              B_0 = blB[0];
              B_1 = blB[1];
              CJMADD(cj,A0,B_0,C0,  B_0);
              CJMADD(cj,A0,B_1,C1,  B_1);
             
              B_0 = blB[2];
              B_1 = blB[3];
              CJMADD(cj,A0,B_0,C2,  B_0);
              CJMADD(cj,A0,B_1,C3,  B_1);
             
              blB += 4;
            }
            res(i, j2 + 0) += alpha * C0;
            res(i, j2 + 1) += alpha * C1;
            res(i, j2 + 2) += alpha * C2;
            res(i, j2 + 3) += alpha * C3;
          }
        }
      }
      // remaining columns
      for(Index j2=packet_cols4; j2<cols; j2++)
00007FF6F87D6403  mov         r8,qword ptr [peeled_mc1] 
00007FF6F87D6407  inc         r12 
00007FF6F87D640A  add         r9,rdi 
00007FF6F87D640D  cmp         r12,r13 
00007FF6F87D6410  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1600h (07FF6F87D6280h) 
00007FF6F87D6416  vzeroupper 
        }
      }
    }
  }
00007FF6F87D6419  lea         r11,[rsp+320h] 
00007FF6F87D6421  mov         rbx,qword ptr [r11+40h] 
00007FF6F87D6425  vmovaps     xmm6,xmmword ptr [r11-10h] 
00007FF6F87D642B  vmovaps     xmm7,xmmword ptr [r11-20h] 
00007FF6F87D6431  vmovaps     xmm8,xmmword ptr [r11-30h] 
00007FF6F87D6437  vmovaps     xmm9,xmmword ptr [r11-40h] 
00007FF6F87D643D  vmovaps     xmm10,xmmword ptr [r11-50h] 
00007FF6F87D6443  vmovaps     xmm11,xmmword ptr [r11-60h] 
00007FF6F87D6449  vmovaps     xmm12,xmmword ptr [r11-70h] 
00007FF6F87D644F  vmovaps     xmm13,xmmword ptr [r11-80h] 
00007FF6F87D6455  vmovaps     xmm14,xmmword ptr [r11-90h] 
00007FF6F87D645E  vmovaps     xmm15,xmmword ptr [r11-0A0h] 
00007FF6F87D6467  mov         rsp,r11 
00007FF6F87D646A  pop         r15 
00007FF6F87D646C  pop         r14 
00007FF6F87D646E  pop         r13 
00007FF6F87D6470  pop         r12 
00007FF6F87D6472  pop         rdi 
00007FF6F87D6473  pop         rsi 
00007FF6F87D6474  pop         rbp 
00007FF6F87D6475  ret 
00007FF6F87D6476  vmovsd      xmm2,qword ptr [alpha] 
00007FF6F87D647B  mov         r11,qword ptr [strideA] 
00007FF6F87D647F  mov         r13,qword ptr [blockB] 
00007FF6F87D6487  mov         r15,qword ptr [strideB] 
      {
        Index actual_panel_end = (std::min)(i1+actual_panel_rows, peeled_mc2);
00007FF6F87D648B  lea         rax,[r9+rcx] 
00007FF6F87D648F  cmp         r12,rax 
00007FF6F87D6492  mov         qword ptr [rbp+60h],rax 
00007FF6F87D6496  mov         rdi,rax 
00007FF6F87D6499  mov         qword ptr [rbp+1D0h],rax 
00007FF6F87D64A0  cmovl       rdi,r12 
00007FF6F87D64A4  mov         qword ptr [actual_panel_end],rdi 
        for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D64A8  test        rbx,rbx 
00007FF6F87D64AB  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1D74h (07FF6F87D69F4h) 
      {
        Index actual_panel_end = (std::min)(i1+actual_panel_rows, peeled_mc2);
00007FF6F87D64B1  xor         ecx,ecx 
00007FF6F87D64B3  lea         rax,[r15*4] 
00007FF6F87D64BB  mov         r10d,2 
00007FF6F87D64C1  mov         qword ptr [actual_panel_end],rcx 
00007FF6F87D64C5  mov         qword ptr [i1],r10 
00007FF6F87D64C9  mov         qword ptr [rbp+18h],rax 
00007FF6F87D64CD  nop         dword ptr [rax] 
        {
          for(Index i=i1; i<actual_panel_end; i+=2*LhsProgress)
00007FF6F87D64D0  mov         r12,r9 
00007FF6F87D64D3  cmp         r9,rdi 
00007FF6F87D64D6  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1D3Fh (07FF6F87D69BFh) 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D64DC  mov         rax,qword ptr [offsetB] 
00007FF6F87D64E4  lea         r15,[r10-1] 
00007FF6F87D64E8  vxorps      ymm0,ymm0,ymm0 
00007FF6F87D64EC  vmovupd     ymm1,ymm0 
00007FF6F87D64F0  vmovaps     xmm0,xmm2 
00007FF6F87D64F4  lea         rax,[rcx+rax*4] 
00007FF6F87D64F8  mov         rcx,qword ptr [blockA] 
00007FF6F87D6500  lea         rax,[rax*8] 
00007FF6F87D6508  add         rax,r13 
00007FF6F87D650B  mov         qword ptr [rbp+40h],rax 
00007FF6F87D650F  mov         rax,r11 
00007FF6F87D6512  shl         rax,6 
00007FF6F87D6516  mov         qword ptr [actual_panel_rows],rax 
00007FF6F87D651A  mov         rax,r9 
00007FF6F87D651D  imul        rax,r11 
00007FF6F87D6521  vbroadcastsd ymm0,xmm0 
00007FF6F87D6526  vmovupd     ymmword ptr [rbp+200h],ymm1 
          }
#undef EIGEN_GEBGP_ONESTEP

          ResPacket R0, R1, R2, R3;
          ResPacket alphav = pset1<ResPacket>(alpha);
00007FF6F87D652E  vmovupd     ymmword ptr [alphav],ymm0 
00007FF6F87D6536  lea         r13,[rcx+rax*8] 
00007FF6F87D653A  nop         word ptr [rax+rax] 
          {
         
          // We selected a 2*Traits::LhsProgress x nr micro block of res which is entirely
          // stored into 2 x nr registers.
         
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(2*Traits::LhsProgress)];
00007FF6F87D6540  mov         rcx,r13 
          prefetch(&blA[0]);
00007FF6F87D6543  prefetcht0  [r13] 

          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
00007FF6F87D6548  mov         r9,qword ptr [r14+8] 
00007FF6F87D654C  lea         r11,[r10-2] 
00007FF6F87D6550  mov         rdx,qword ptr [r14] 
          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
00007FF6F87D6553  lea         rax,[r10+1] 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D6557  mov         rbx,r9 
          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
00007FF6F87D655A  mov         rdi,r10 

          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
00007FF6F87D655D  imul        r11,r9 
          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
00007FF6F87D6561  imul        rdi,r9 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D6565  imul        rbx,r15 
          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
00007FF6F87D6569  imul        r9,rax 

          LinearMapper r0 = res.getLinearMapper(i, j2 + 0);
00007FF6F87D656D  add         r11,r12 
          LinearMapper r2 = res.getLinearMapper(i, j2 + 2);
00007FF6F87D6570  add         rdi,r12 
          LinearMapper r1 = res.getLinearMapper(i, j2 + 1);
00007FF6F87D6573  add         rbx,r12 

          // gets res block as register
          AccPacket C0, C1, C2, C3,
                    C4, C5, C6, C7;
          traits.initAcc(C0); traits.initAcc(C1); traits.initAcc(C2); traits.initAcc(C3);
00007FF6F87D6576  vmovupd     ymm8,ymm1 
00007FF6F87D657A  vmovupd     ymm10,ymm1 
00007FF6F87D657E  vmovupd     ymm12,ymm1 
          LinearMapper r3 = res.getLinearMapper(i, j2 + 3);
00007FF6F87D6582  add         r9,r12 

          // gets res block as register
          AccPacket C0, C1, C2, C3,
                    C4, C5, C6, C7;
          traits.initAcc(C0); traits.initAcc(C1); traits.initAcc(C2); traits.initAcc(C3);
00007FF6F87D6585  vmovupd     ymm14,ymm1 
          traits.initAcc(C4); traits.initAcc(C5); traits.initAcc(C6); traits.initAcc(C7);
00007FF6F87D6589  vmovupd     ymm9,ymm1 
00007FF6F87D658D  vmovupd     ymm11,ymm1 
00007FF6F87D6591  vmovupd     ymm13,ymm1 
00007FF6F87D6595  vmovupd     ymm15,ymm1 

          r0.prefetch(prefetch_res_offset);
00007FF6F87D6599  prefetcht0  [rdx+r11*8+20h] 
          r1.prefetch(prefetch_res_offset);
00007FF6F87D659F  prefetcht0  [rdx+rbx*8+20h] 
          r2.prefetch(prefetch_res_offset);
00007FF6F87D65A4  prefetcht0  [rdx+rdi*8+20h] 
          r3.prefetch(prefetch_res_offset);
00007FF6F87D65A9  prefetcht0  [rdx+r9*8+20h] 

          // performs "inner" products
          const RhsScalar* blB = &blockB[j2*strideB+offsetB*nr];
00007FF6F87D65AF  mov         r15,qword ptr [rbp+40h] 
          prefetch(&blB[0]);
00007FF6F87D65B3  prefetcht0  [r15] 
          LhsPacket A0, A1;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D65B7  test        r8,r8 
00007FF6F87D65BA  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1C0Ch (07FF6F87D688Ch) 
          {
         
          // We selected a 2*Traits::LhsProgress x nr micro block of res which is entirely
          // stored into 2 x nr registers.
         
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(2*Traits::LhsProgress)];
00007FF6F87D65C0  lea         r10,[r8-1] 
00007FF6F87D65C4  shr         r10,3 
00007FF6F87D65C8  lea         rax,[r15+30h] 
00007FF6F87D65CC  inc         r10 
00007FF6F87D65CF  nop 
          {
            EIGEN_ASM_COMMENT("begin gebp micro kernel 2pX4");
            RhsPacket B_0, B1, B2, B3, T0;

   #define EIGEN_GEBGP_ONESTEP(K) \
            do {                                                                \
              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 2pX4");        \
              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
              traits.loadLhs(&blA[(0+2*K)*LhsProgress], A0);                    \
              traits.loadLhs(&blA[(1+2*K)*LhsProgress], A1);                    \
              traits.broadcastRhs(&blB[(0+4*K)*RhsProgress], B_0, B1, B2, B3);  \
              traits.madd(A0, B_0, C0, T0);                                     \
              traits.madd(A1, B_0, C4, B_0);                                    \
              traits.madd(A0, B1,  C1, T0);                                     \
              traits.madd(A1, B1,  C5, B1);                                     \
              traits.madd(A0, B2,  C2, T0);                                     \
              traits.madd(A1, B2,  C6, B2);                                     \
              traits.madd(A0, B3,  C3, T0);                                     \
              traits.madd(A1, B3,  C7, B3);                                     \
              EIGEN_ASM_COMMENT("end step of gebp micro kernel 2pX4");          \
            } while(false)
           
            internal::prefetch(blB+(48+0));
00007FF6F87D65D0  prefetcht0  [rax+150h] 
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D65D7  vmovupd     ymm6,ymmword ptr [rcx] 
00007FF6F87D65DB  vmovupd     ymm7,ymmword ptr [rcx+20h] 
00007FF6F87D65E0  vbroadcastsd ymm2,mmword ptr [r15] 
00007FF6F87D65E5  vbroadcastsd ymm3,mmword ptr [rax-28h] 
00007FF6F87D65EB  vbroadcastsd ymm0,mmword ptr [rax-20h] 
00007FF6F87D65F1  vbroadcastsd ymm1,mmword ptr [rax-18h] 
00007FF6F87D65F7  vfmadd231pd ymm8,ymm6,ymm2 
00007FF6F87D65FC  vfmadd231pd ymm9,ymm7,ymm2 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6601  vbroadcastsd ymm2,mmword ptr [rax-10h] 
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D6607  vfmadd231pd ymm10,ymm6,ymm3 
00007FF6F87D660C  vfmadd231pd ymm11,ymm7,ymm3 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6611  vbroadcastsd ymm3,mmword ptr [rax-8] 
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D6617  vfmadd231pd ymm12,ymm6,ymm0 
00007FF6F87D661C  vfmadd231pd ymm13,ymm7,ymm0 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6621  vbroadcastsd ymm0,mmword ptr [rax] 
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D6626  vfmadd231pd ymm14,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D662B  vmovupd     ymm6,ymmword ptr [rcx+40h] 
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D6630  vfmadd231pd ymm15,ymm7,ymm1 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6635  vmovupd     ymm7,ymmword ptr [rcx+60h] 
00007FF6F87D663A  vbroadcastsd ymm1,mmword ptr [rax+8] 
00007FF6F87D6640  vfmadd231pd ymm8,ymm6,ymm2 
00007FF6F87D6645  vfmadd231pd ymm9,ymm7,ymm2 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D664A  vbroadcastsd ymm2,mmword ptr [rax+10h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6650  vfmadd231pd ymm10,ymm6,ymm3 
00007FF6F87D6655  vfmadd231pd ymm11,ymm7,ymm3 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D665A  vbroadcastsd ymm3,mmword ptr [rax+18h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6660  vfmadd231pd ymm12,ymm6,ymm0 
00007FF6F87D6665  vfmadd231pd ymm13,ymm7,ymm0 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D666A  vbroadcastsd ymm0,mmword ptr [rax+20h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6670  vfmadd231pd ymm14,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D6675  vmovupd     ymm6,ymmword ptr [rcx+80h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D667D  vfmadd231pd ymm15,ymm7,ymm1 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D6682  vmovupd     ymm7,ymmword ptr [rcx+0A0h] 
00007FF6F87D668A  vbroadcastsd ymm1,mmword ptr [rax+28h] 
00007FF6F87D6690  vfmadd231pd ymm8,ymm6,ymm2 
00007FF6F87D6695  vfmadd231pd ymm9,ymm7,ymm2 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D669A  vbroadcastsd ymm2,mmword ptr [rax+30h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D66A0  vfmadd231pd ymm10,ymm6,ymm3 
00007FF6F87D66A5  vfmadd231pd ymm11,ymm7,ymm3 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D66AA  vbroadcastsd ymm3,mmword ptr [rax+38h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D66B0  vfmadd231pd ymm12,ymm6,ymm0 
00007FF6F87D66B5  vfmadd231pd ymm13,ymm7,ymm0 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D66BA  vbroadcastsd ymm0,mmword ptr [rax+40h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D66C0  vfmadd231pd ymm14,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D66C5  vmovupd     ymm6,ymmword ptr [rcx+0C0h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D66CD  vfmadd231pd ymm15,ymm7,ymm1 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D66D2  vmovupd     ymm7,ymmword ptr [rcx+0E0h] 
00007FF6F87D66DA  vbroadcastsd ymm1,mmword ptr [rax+48h] 
00007FF6F87D66E0  vfmadd231pd ymm8,ymm6,ymm2 
00007FF6F87D66E5  vfmadd231pd ymm9,ymm7,ymm2 
00007FF6F87D66EA  vfmadd231pd ymm10,ymm6,ymm3 
00007FF6F87D66EF  vfmadd231pd ymm11,ymm7,ymm3 
00007FF6F87D66F4  vfmadd231pd ymm12,ymm6,ymm0 
00007FF6F87D66F9  vfmadd231pd ymm13,ymm7,ymm0 
00007FF6F87D66FE  vfmadd231pd ymm14,ymm6,ymm1 
00007FF6F87D6703  vfmadd231pd ymm15,ymm7,ymm1 
            internal::prefetch(blB+(48+16));
00007FF6F87D6708  prefetcht0  [rax+1D0h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D670F  vmovupd     ymm6,ymmword ptr [rcx+100h] 
00007FF6F87D6717  vmovupd     ymm7,ymmword ptr [rcx+120h] 
00007FF6F87D671F  vbroadcastsd ymm2,mmword ptr [rax+50h] 
00007FF6F87D6725  vbroadcastsd ymm3,mmword ptr [rax+58h] 
00007FF6F87D672B  vbroadcastsd ymm0,mmword ptr [rax+60h] 
00007FF6F87D6731  vbroadcastsd ymm1,mmword ptr [rax+68h] 
00007FF6F87D6737  vfmadd231pd ymm8,ymm6,ymm2 
00007FF6F87D673C  vfmadd231pd ymm9,ymm7,ymm2 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D6741  vbroadcastsd ymm2,mmword ptr [rax+70h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D6747  vfmadd231pd ymm10,ymm6,ymm3 
00007FF6F87D674C  vfmadd231pd ymm11,ymm7,ymm3 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D6751  vbroadcastsd ymm3,mmword ptr [rax+78h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D6757  vfmadd231pd ymm12,ymm6,ymm0 
00007FF6F87D675C  vfmadd231pd ymm13,ymm7,ymm0 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D6761  vbroadcastsd ymm0,mmword ptr [rax+80h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D676A  vfmadd231pd ymm14,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D676F  vmovupd     ymm6,ymmword ptr [rcx+140h] 
00007FF6F87D6777  vfmadd231pd ymm15,ymm7,ymm1 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D677C  vmovupd     ymm7,ymmword ptr [rcx+160h] 
00007FF6F87D6784  vbroadcastsd ymm1,mmword ptr [rax+88h] 
00007FF6F87D678D  vfmadd231pd ymm8,ymm6,ymm2 
00007FF6F87D6792  vfmadd231pd ymm9,ymm7,ymm2 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D6797  vbroadcastsd ymm2,mmword ptr [rax+90h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D67A0  vfmadd231pd ymm10,ymm6,ymm3 
00007FF6F87D67A5  vfmadd231pd ymm11,ymm7,ymm3 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D67AA  vbroadcastsd ymm3,mmword ptr [rax+98h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D67B3  vfmadd231pd ymm12,ymm6,ymm0 
00007FF6F87D67B8  vfmadd231pd ymm13,ymm7,ymm0 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D67BD  vbroadcastsd ymm0,mmword ptr [rax+0A0h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D67C6  vfmadd231pd ymm14,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D67CB  vmovupd     ymm6,ymmword ptr [rcx+180h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D67D3  vfmadd231pd ymm15,ymm7,ymm1 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D67D8  vmovupd     ymm7,ymmword ptr [rcx+1A0h] 
00007FF6F87D67E0  vbroadcastsd ymm1,mmword ptr [rax+0A8h] 
00007FF6F87D67E9  vfmadd231pd ymm8,ymm6,ymm2 
00007FF6F87D67EE  vfmadd231pd ymm9,ymm7,ymm2 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D67F3  vbroadcastsd ymm2,mmword ptr [rax+0B0h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D67FC  vfmadd231pd ymm10,ymm6,ymm3 
00007FF6F87D6801  vfmadd231pd ymm11,ymm7,ymm3 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D6806  vbroadcastsd ymm3,mmword ptr [rax+0B8h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D680F  vfmadd231pd ymm12,ymm6,ymm0 
00007FF6F87D6814  vfmadd231pd ymm13,ymm7,ymm0 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D6819  vbroadcastsd ymm0,mmword ptr [rax+0C0h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D6822  vfmadd231pd ymm14,ymm6,ymm1 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D6827  vmovupd     ymm6,ymmword ptr [rcx+1C0h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D682F  vfmadd231pd ymm15,ymm7,ymm1 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D6834  vmovupd     ymm7,ymmword ptr [rcx+1E0h] 
00007FF6F87D683C  vbroadcastsd ymm1,mmword ptr [rax+0C8h] 

            blB += pk*4*RhsProgress;
            blA += pk*(2*Traits::LhsProgress);
00007FF6F87D6845  add         rcx,200h 
00007FF6F87D684C  lea         rax,[rax+100h] 
00007FF6F87D6853  add         r15,100h 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D685A  vfmadd231pd ymm8,ymm6,ymm2 
00007FF6F87D685F  vfmadd231pd ymm9,ymm7,ymm2 
00007FF6F87D6864  vfmadd231pd ymm10,ymm6,ymm3 
00007FF6F87D6869  vfmadd231pd ymm11,ymm7,ymm3 
00007FF6F87D686E  vfmadd231pd ymm12,ymm6,ymm0 
00007FF6F87D6873  vfmadd231pd ymm13,ymm7,ymm0 
00007FF6F87D6878  vfmadd231pd ymm14,ymm6,ymm1 
00007FF6F87D687D  vfmadd231pd ymm15,ymm7,ymm1 
          LhsPacket A0, A1;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D6882  sub         r10,1 
00007FF6F87D6886  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1950h (07FF6F87D65D0h) 

            EIGEN_ASM_COMMENT("end gebp micro kernel 2pX4");
          }
          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D688C  cmp         r8,rsi 
00007FF6F87D688F  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1C76h (07FF6F87D68F6h) 
00007FF6F87D6891  mov         r10,rsi 
00007FF6F87D6894  lea         rax,[r15+10h] 
00007FF6F87D6898  sub         r10,r8 
00007FF6F87D689B  nop         dword ptr [rax+rax] 
          {
            RhsPacket B_0, B1, B2, B3, T0;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D68A0  vmovupd     ymm6,ymmword ptr [rcx] 
00007FF6F87D68A4  vmovupd     ymm7,ymmword ptr [rcx+20h] 
00007FF6F87D68A9  vbroadcastsd ymm2,mmword ptr [rax-10h] 
00007FF6F87D68AF  vbroadcastsd ymm3,mmword ptr [rax-8] 
00007FF6F87D68B5  vbroadcastsd ymm0,mmword ptr [rax] 
00007FF6F87D68BA  vbroadcastsd ymm1,mmword ptr [rax+8] 
            blB += 4*RhsProgress;
00007FF6F87D68C0  lea         rax,[rax+20h] 
            blA += 2*Traits::LhsProgress;
00007FF6F87D68C4  lea         rcx,[rcx+40h] 
          {
            RhsPacket B_0, B1, B2, B3, T0;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D68C8  vfmadd231pd ymm8,ymm6,ymm2 
00007FF6F87D68CD  vfmadd231pd ymm9,ymm7,ymm2 
00007FF6F87D68D2  vfmadd231pd ymm10,ymm6,ymm3 
00007FF6F87D68D7  vfmadd231pd ymm11,ymm7,ymm3 
00007FF6F87D68DC  vfmadd231pd ymm12,ymm6,ymm0 
00007FF6F87D68E1  vfmadd231pd ymm13,ymm7,ymm0 
00007FF6F87D68E6  vfmadd231pd ymm14,ymm6,ymm1 
00007FF6F87D68EB  vfmadd231pd ymm15,ymm7,ymm1 

            EIGEN_ASM_COMMENT("end gebp micro kernel 2pX4");
          }
          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D68F0  sub         r10,1 
00007FF6F87D68F4  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1C20h (07FF6F87D68A0h) 

          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
          R1 = r0.loadPacket(1 * Traits::ResPacketSize);
00007FF6F87D68F6  vmovupd     ymm6,ymmword ptr [rdx+r11*8+20h] 
          R3 = r1.loadPacket(1 * Traits::ResPacketSize);
          traits.acc(C0, alphav, R0);
00007FF6F87D68FD  vmovupd     ymm0,ymmword ptr [rdx+r11*8] 
          R2 = r1.loadPacket(0 * Traits::ResPacketSize);
00007FF6F87D6903  vmovupd     ymm5,ymmword ptr [rdx+rbx*8] 
          traits.acc(C5, alphav, R3);
00007FF6F87D6908  vmovupd     ymm3,ymmword ptr [rdx+rbx*8+20h] 
          traits.acc(C4, alphav, R1);
00007FF6F87D690E  vfmadd231pd ymm6,ymm9,ymmword ptr [alphav] 
          traits.acc(C1, alphav, R2);
00007FF6F87D6917  vmovupd     ymm9,ymmword ptr [alphav] 
        {
          for(Index i=i1; i<actual_panel_end; i+=2*LhsProgress)
00007FF6F87D691F  mov         r10,qword ptr [rbp+10h] 
00007FF6F87D6923  add         r12,8 
00007FF6F87D6927  add         r13,qword ptr [rbp+70h] 
00007FF6F87D692B  vmovupd     ymm1,ymmword ptr [rbp+200h] 
          R3 = r1.loadPacket(1 * Traits::ResPacketSize);
          traits.acc(C0, alphav, R0);
00007FF6F87D6933  vfmadd231pd ymm0,ymm8,ymm9 
          r0.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D6938  vmovupd     ymmword ptr [rdx+r11*8],ymm0 
          r0.storePacket(1 * Traits::ResPacketSize, R1);
00007FF6F87D693E  vmovupd     ymmword ptr [rdx+r11*8+20h],ymm6 
          traits.acc(C1, alphav, R2);
00007FF6F87D6945  vfmadd231pd ymm5,ymm10,ymm9 
          r1.storePacket(0 * Traits::ResPacketSize, R2);
00007FF6F87D694A  vmovupd     ymmword ptr [rdx+rbx*8],ymm5 
          traits.acc(C5, alphav, R3);
00007FF6F87D694F  vfmadd231pd ymm3,ymm11,ymm9 
          r1.storePacket(1 * Traits::ResPacketSize, R3);
00007FF6F87D6954  vmovupd     ymmword ptr [rdx+rbx*8+20h],ymm3 
          R3 = r3.loadPacket(1 * Traits::ResPacketSize);
          traits.acc(C2,  alphav, R0);
00007FF6F87D695A  vmovupd     ymm0,ymmword ptr [rdx+rdi*8] 

          R0 = r2.loadPacket(0 * Traits::ResPacketSize);
          R1 = r2.loadPacket(1 * Traits::ResPacketSize);
00007FF6F87D695F  vmovupd     ymm6,ymmword ptr [rdx+rdi*8+20h] 
          R2 = r3.loadPacket(0 * Traits::ResPacketSize);
00007FF6F87D6965  vmovupd     ymm5,ymmword ptr [rdx+r9*8] 
          traits.acc(C7,  alphav, R3);
00007FF6F87D696B  vmovupd     ymm3,ymmword ptr [rdx+r9*8+20h] 
          R3 = r3.loadPacket(1 * Traits::ResPacketSize);
          traits.acc(C2,  alphav, R0);
00007FF6F87D6972  vfmadd231pd ymm0,ymm12,ymm9 
          r2.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D6977  vmovupd     ymmword ptr [rdx+rdi*8],ymm0 
          traits.acc(C6,  alphav, R1);
00007FF6F87D697C  vfmadd231pd ymm6,ymm13,ymm9 
          r2.storePacket(1 * Traits::ResPacketSize, R1);
00007FF6F87D6981  vmovupd     ymmword ptr [rdx+rdi*8+20h],ymm6 
        {
          for(Index i=i1; i<actual_panel_end; i+=2*LhsProgress)
00007FF6F87D6987  mov         rdi,qword ptr [actual_panel_end] 
00007FF6F87D698B  lea         r15,[r10-1] 
          traits.acc(C3,  alphav, R2);
00007FF6F87D698F  vfmadd231pd ymm5,ymm14,ymm9 
          traits.acc(C7,  alphav, R3);
00007FF6F87D6994  vfmadd231pd ymm3,ymm15,ymm9 
          r3.storePacket(0 * Traits::ResPacketSize, R2);
00007FF6F87D6999  vmovupd     ymmword ptr [rdx+r9*8],ymm5 
          r3.storePacket(1 * Traits::ResPacketSize, R3);
00007FF6F87D699F  vmovupd     ymmword ptr [rdx+r9*8+20h],ymm3 
        {
          for(Index i=i1; i<actual_panel_end; i+=2*LhsProgress)
00007FF6F87D69A6  cmp         r12,rdi 
00007FF6F87D69A9  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+18C0h (07FF6F87D6540h) 
00007FF6F87D69AF  mov         r9,qword ptr [rbp] 
00007FF6F87D69B3  mov         rcx,qword ptr [rbp+38h] 
00007FF6F87D69B7  mov         rax,qword ptr [rbp+18h] 
00007FF6F87D69BB  mov         rbx,qword ptr [j2] 
        for(Index j2=0; j2<packet_cols4; j2+=nr)
00007FF6F87D69BF  vmovsd      xmm2,qword ptr [alpha] 
00007FF6F87D69C4  mov         r11,qword ptr [strideA] 
00007FF6F87D69C8  add         rcx,rax 
00007FF6F87D69CB  mov         r13,qword ptr [blockB] 
00007FF6F87D69D3  add         r10,4 
00007FF6F87D69D7  mov         qword ptr [rbp+10h],r10 
00007FF6F87D69DB  mov         qword ptr [rbp+38h],rcx 
00007FF6F87D69DF  lea         rax,[r10-2] 
00007FF6F87D69E3  cmp         rax,rbx 
00007FF6F87D69E6  mov         rax,qword ptr [rbp+18h] 
00007FF6F87D69EA  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1850h (07FF6F87D64D0h) 
00007FF6F87D69F0  mov         r12,qword ptr [peeled_mc2] 
          }
        }
     
        // Deal with remaining columns of the rhs
        for(Index j2=packet_cols4; j2<cols; j2++)
00007FF6F87D69F4  mov         r15,rbx 
00007FF6F87D69F7  vmovsd      xmm13,qword ptr [alpha] 
00007FF6F87D69FC  cmp         rbx,qword ptr [cols] 
00007FF6F87D6A04  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1F8Fh (07FF6F87D6C0Fh) 
00007FF6F87D6A0A  mov         rcx,qword ptr [strideB] 
00007FF6F87D6A0E  lea         rax,[rcx*8] 
00007FF6F87D6A16  mov         qword ptr [rbp+18h],rax 
00007FF6F87D6A1A  mov         rax,rbx 
00007FF6F87D6A1D  imul        rax,rcx 
00007FF6F87D6A21  mov         rcx,qword ptr [blockB] 
00007FF6F87D6A29  add         rax,qword ptr [offsetB] 
00007FF6F87D6A31  lea         r13,[rcx+rax*8] 
00007FF6F87D6A35  mov         rax,qword ptr [rbp+18h] 
00007FF6F87D6A39  mov         rcx,qword ptr [cols] 
        {
          for(Index i=i1; i<actual_panel_end; i+=2*LhsProgress)
00007FF6F87D6A41  mov         rbx,r9 
00007FF6F87D6A44  cmp         r9,rdi 
00007FF6F87D6A47  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1F78h (07FF6F87D6BF8h) 
00007FF6F87D6A4D  mov         r12,qword ptr [strideA] 
00007FF6F87D6A51  mov         rax,r9 
00007FF6F87D6A54  mov         rcx,qword ptr [blockA] 
00007FF6F87D6A5C  shl         r12,6 
00007FF6F87D6A60  imul        rax,qword ptr [strideA] 
00007FF6F87D6A65  vmovaps     xmm1,xmm13 
00007FF6F87D6A6A  vxorps      ymm7,ymm0,ymm0 
00007FF6F87D6A6E  vbroadcastsd ymm8,xmm1 
00007FF6F87D6A73  lea         r11,[rcx+rax*8] 
00007FF6F87D6A77  nop         word ptr [rax+rax] 
          {
          // One column at a time
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(2*Traits::LhsProgress)];
00007FF6F87D6A80  mov         rax,r11 
          prefetch(&blA[0]);
00007FF6F87D6A83  prefetcht0  [r11] 

          LinearMapper r0 = res.getLinearMapper(i, j2);
00007FF6F87D6A87  mov         r10,qword ptr [r14] 
00007FF6F87D6A8A  mov         r9,r15 
00007FF6F87D6A8D  imul        r9,qword ptr [r14+8] 

          // gets res block as register
          AccPacket C0, C4;
          traits.initAcc(C0);
00007FF6F87D6A92  vmovupd     ymm5,ymm7 

          LinearMapper r0 = res.getLinearMapper(i, j2);
00007FF6F87D6A96  add         r9,rbx 
          traits.initAcc(C4);
00007FF6F87D6A99  vmovupd     ymm6,ymm7 
          r0.prefetch(prefetch_res_offset);
00007FF6F87D6A9D  prefetcht0  [r10+r9*8+20h] 

          // performs "inner" products
          const RhsScalar* blB = &blockB[j2*strideB+offsetB];
          LhsPacket A0, A1;

          for(Index k=0; k<peeled_kc; k+=pk)
00007FF6F87D6AA3  mov         rcx,r13 
00007FF6F87D6AA6  test        r8,r8 
00007FF6F87D6AA9  jle         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1F06h (07FF6F87D6B86h) 
          {
          // One column at a time
          const LhsScalar* blA = &blockA[i*strideA+offsetA*(2*Traits::LhsProgress)];
00007FF6F87D6AAF  lea         rdx,[r8-1] 
00007FF6F87D6AB3  shr         rdx,3 
00007FF6F87D6AB7  inc         rdx 
00007FF6F87D6ABA  nop         word ptr [rax+rax] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6AC0  vbroadcastsd ymm1,mmword ptr [rcx+8] 
          {
            EIGEN_ASM_COMMENT("begin gebp micro kernel 2pX1");
            RhsPacket B_0, B1;
       
#define EIGEN_GEBGP_ONESTEP(K) \
            do {                                                                  \
              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 2pX1");          \
              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
              traits.loadLhs(&blA[(0+2*K)*LhsProgress], A0);                      \
              traits.loadLhs(&blA[(1+2*K)*LhsProgress], A1);                      \
              traits.loadRhs(&blB[(0+K)*RhsProgress], B_0);                       \
              traits.madd(A0, B_0, C0, B1);                                       \
              traits.madd(A1, B_0, C4, B_0);                                      \
              EIGEN_ASM_COMMENT("end step of gebp micro kernel 2pX1");            \
            } while(false)
       
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D6AC6  vbroadcastsd ymm0,mmword ptr [rcx] 
00007FF6F87D6ACB  vfmadd231pd ymm5,ymm0,ymmword ptr [rax] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6AD0  vfmadd231pd ymm5,ymm1,ymmword ptr [rax+40h] 
          {
            EIGEN_ASM_COMMENT("begin gebp micro kernel 2pX1");
            RhsPacket B_0, B1;
       
#define EIGEN_GEBGP_ONESTEP(K) \
            do {                                                                  \
              EIGEN_ASM_COMMENT("begin step of gebp micro kernel 2pX1");          \
              EIGEN_ASM_COMMENT("Note: these asm comments work around bug 935!"); \
              traits.loadLhs(&blA[(0+2*K)*LhsProgress], A0);                      \
              traits.loadLhs(&blA[(1+2*K)*LhsProgress], A1);                      \
              traits.loadRhs(&blB[(0+K)*RhsProgress], B_0);                       \
              traits.madd(A0, B_0, C0, B1);                                       \
              traits.madd(A1, B_0, C4, B_0);                                      \
              EIGEN_ASM_COMMENT("end step of gebp micro kernel 2pX1");            \
            } while(false)
       
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D6AD6  vfmadd231pd ymm6,ymm0,ymmword ptr [rax+20h] 
            EIGEN_GEBGP_ONESTEP(1);
00007FF6F87D6ADC  vfmadd231pd ymm6,ymm1,ymmword ptr [rax+60h] 
            EIGEN_GEBGP_ONESTEP(2);
00007FF6F87D6AE2  vbroadcastsd ymm1,mmword ptr [rcx+10h] 
00007FF6F87D6AE8  vfmadd231pd ymm5,ymm1,ymmword ptr [rax+80h] 
00007FF6F87D6AF1  vfmadd231pd ymm6,ymm1,ymmword ptr [rax+0A0h] 
            EIGEN_GEBGP_ONESTEP(3);
00007FF6F87D6AFA  vbroadcastsd ymm1,mmword ptr [rcx+18h] 
00007FF6F87D6B00  vfmadd231pd ymm5,ymm1,ymmword ptr [rax+0C0h] 
00007FF6F87D6B09  vfmadd231pd ymm6,ymm1,ymmword ptr [rax+0E0h] 
            EIGEN_GEBGP_ONESTEP(4);
00007FF6F87D6B12  vbroadcastsd ymm1,mmword ptr [rcx+20h] 
00007FF6F87D6B18  vfmadd231pd ymm5,ymm1,ymmword ptr [rax+100h] 
00007FF6F87D6B21  vfmadd231pd ymm6,ymm1,ymmword ptr [rax+120h] 
            EIGEN_GEBGP_ONESTEP(5);
00007FF6F87D6B2A  vbroadcastsd ymm1,mmword ptr [rcx+28h] 
00007FF6F87D6B30  vfmadd231pd ymm5,ymm1,ymmword ptr [rax+140h] 
00007FF6F87D6B39  vfmadd231pd ymm6,ymm1,ymmword ptr [rax+160h] 
            EIGEN_GEBGP_ONESTEP(6);
00007FF6F87D6B42  vbroadcastsd ymm1,mmword ptr [rcx+30h] 
00007FF6F87D6B48  vfmadd231pd ymm5,ymm1,ymmword ptr [rax+180h] 
00007FF6F87D6B51  vfmadd231pd ymm6,ymm1,ymmword ptr [rax+1A0h] 
            EIGEN_GEBGP_ONESTEP(7);
00007FF6F87D6B5A  vbroadcastsd ymm1,mmword ptr [rcx+38h] 
00007FF6F87D6B60  vfmadd231pd ymm5,ymm1,ymmword ptr [rax+1C0h] 
00007FF6F87D6B69  vfmadd231pd ymm6,ymm1,ymmword ptr [rax+1E0h] 

            blB += pk*RhsProgress;
            blA += pk*2*Traits::LhsProgress;
00007FF6F87D6B72  add         rax,200h 
00007FF6F87D6B78  add         rcx,40h 
00007FF6F87D6B7C  sub         rdx,1 
00007FF6F87D6B80  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1E40h (07FF6F87D6AC0h) 

            EIGEN_ASM_COMMENT("end gebp micro kernel 2pX1");
          }

          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D6B86  cmp         r8,rsi 
00007FF6F87D6B89  jge         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1F30h (07FF6F87D6BB0h) 
00007FF6F87D6B8B  mov         rdx,rsi 
00007FF6F87D6B8E  sub         rdx,r8 
            blA += 2*Traits::LhsProgress;
00007FF6F87D6B91  lea         rax,[rax+40h] 
          {
            RhsPacket B_0, B1;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D6B95  vbroadcastsd ymm0,mmword ptr [rcx] 
            blB += RhsProgress;
00007FF6F87D6B9A  lea         rcx,[rcx+8] 
          {
            RhsPacket B_0, B1;
            EIGEN_GEBGP_ONESTEP(0);
00007FF6F87D6B9E  vfmadd231pd ymm5,ymm0,ymmword ptr [rax-40h] 
00007FF6F87D6BA4  vfmadd231pd ymm6,ymm0,ymmword ptr [rax-20h] 

            EIGEN_ASM_COMMENT("end gebp micro kernel 2pX1");
          }

          // process remaining peeled loop
          for(Index k=peeled_kc; k<depth; k++)
00007FF6F87D6BAA  sub         rdx,1 
00007FF6F87D6BAE  jne         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1F11h (07FF6F87D6B91h) 
          }
#undef EIGEN_GEBGP_ONESTEP
          ResPacket R0, R1;
          ResPacket alphav = pset1<ResPacket>(alpha);

          R0 = r0.loadPacket(0 * Traits::ResPacketSize);
00007FF6F87D6BB0  vmovupd     ymm3,ymmword ptr [r10+r9*8] 
          R1 = r0.loadPacket(1 * Traits::ResPacketSize);
00007FF6F87D6BB6  vmovupd     ymm2,ymmword ptr [r10+r9*8+20h] 
          traits.acc(C0, alphav, R0);
00007FF6F87D6BBD  vmovupd     ymm1,ymm3 
00007FF6F87D6BC1  vfmadd231pd ymm1,ymm5,ymm8 
        {
          for(Index i=i1; i<actual_panel_end; i+=2*LhsProgress)
00007FF6F87D6BC6  add         rbx,8 
00007FF6F87D6BCA  add         r11,r12 
          traits.acc(C4, alphav, R1);
00007FF6F87D6BCD  vfmadd231pd ymm2,ymm6,ymm8 
          r0.storePacket(0 * Traits::ResPacketSize, R0);
00007FF6F87D6BD2  vmovupd     ymmword ptr [r10+r9*8],ymm1 
          r0.storePacket(1 * Traits::ResPacketSize, R1);
00007FF6F87D6BD8  vmovupd     ymmword ptr [r10+r9*8+20h],ymm2 
        {
          for(Index i=i1; i<actual_panel_end; i+=2*LhsProgress)
00007FF6F87D6BDF  cmp         rbx,rdi 
00007FF6F87D6BE2  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1E00h (07FF6F87D6A80h) 
00007FF6F87D6BE8  mov         r9,qword ptr [rbp] 
00007FF6F87D6BEC  mov         rax,qword ptr [rbp+18h] 
00007FF6F87D6BF0  mov         rcx,qword ptr [cols] 
          }
        }
     
        // Deal with remaining columns of the rhs
        for(Index j2=packet_cols4; j2<cols; j2++)
00007FF6F87D6BF8  inc         r15 
00007FF6F87D6BFB  add         r13,rax 
00007FF6F87D6BFE  cmp         r15,rcx 
00007FF6F87D6C01  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+1DC1h (07FF6F87D6A41h) 
00007FF6F87D6C07  mov         r12,qword ptr [peeled_mc2] 
00007FF6F87D6C0B  mov         rbx,qword ptr [j2] 

      for(Index i1=peeled_mc3; i1<peeled_mc2; i1+=actual_panel_rows)
00007FF6F87D6C0F  mov         r9,qword ptr [rbp+60h] 
00007FF6F87D6C13  mov         rcx,qword ptr [actual_panel_rows] 
00007FF6F87D6C17  mov         qword ptr [rbp],r9 
00007FF6F87D6C1B  cmp         r9,r12 
00007FF6F87D6C1E  jl          Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+17F6h (07FF6F87D6476h) 
00007FF6F87D6C24  jmp         Eigen::internal::gebp_kernel<double,double,__int64,Eigen::internal::blas_data_mapper<double,__int64,0,0>,12,4,0,0>::operator()+0E84h (07FF6F87D5B04h) 
--- No source file -------------------------------------------------------------
00007FF6F87D6C29  int         3 
00007FF6F87D6C2A  int         3 
00007FF6F87D6C2B  int         3 
00007FF6F87D6C2C  int         3 
00007FF6F87D6C2D  int         3 
00007FF6F87D6C2E  int         3 
00007FF6F87D6C2F  int         3 
--- c:\src\eigen\eigen\src\core\products\generalblockpanelkernel.h -------------

User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: partialPivLu performance

Wed May 04, 2016 9:29 am
Thank you for the asm. As I guessed, MSVC fails to properly allocate register and it stupidly introduces costly register spilling though our code is designed in a way that the register allocator has nothing to do: we declare 16 variables (=number of registers) and perform all operations in a way that no temporary is required.

I don't know how to workaround this.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: partialPivLu performance

Wed May 04, 2016 9:40 am
Actually, we has a similar issue with clang/gcc on ARM targets that we fixed by adding inline assembly comments to break the optimizer. You could try them by defining:

#define EIGEN_ASM_COMMENT(X) __asm { ; X }

before including Eigen.


Also, the interesting part of the generated assembly are the following the first occurence of "EIGEN_GEBP_ONESTEP(0);" where you can see problematic register copies wasting registers:

00007FF6F87D4FAE vmovupd ymm6,ymm0
00007FF6F87D4FB2 vmovupd ymm7,ymm8
00007FF6F87D4FB7 vmovupd ymm8,ymm11

as well as register spilling such as:

00007FF6F87D4FF3 vmovupd ymm0,ymmword ptr [C3]
00007FF6F87D5010 vmovupd ymmword ptr [C5],ymm0

The variables C* should stay in registers...
jcm
Registered Member
Posts
5
Karma
0

Re: partialPivLu performance

Wed May 04, 2016 12:35 pm
ggael wrote:Actually, we has a similar issue with clang/gcc on ARM targets that we fixed by adding inline assembly comments to break the optimizer. You could try them by defining:
#define EIGEN_ASM_COMMENT(X) __asm { ; X }
before including Eigen.


Thanks for the explanations about the asm output.

I tried your suggestion with the `__asm` comment. Unfortunately, it seems that MSVC doesn't support inline assembler on x64 [1]. I get `Error C4235 nonstandard extension used: '__asm' keyword not supported on this architecture`.

Is there any point in trying using a compiler intrinsics instead [2]? After reading [3], I guess I'm out of luck.

[1] https://msdn.microsoft.com/en-us/library/wbk4z78b.aspx
[2] https://msdn.microsoft.com/en-us/library/hh977022.aspx
[3] http://stackoverflow.com/questions/13955162/why-does-adding-assembly-comments-cause-such-radical-change-in-generated-code
tienhung
Registered Member
Posts
29
Karma
0

Re: partialPivLu performance

Fri May 06, 2016 1:31 pm
Intel Compiler C++ can be integrated in MCVS and I guess that it fully supports inline assembly
https://software.intel.com/en-us/node/513428
jcm
Registered Member
Posts
5
Karma
0

Re: partialPivLu performance

Fri May 06, 2016 6:55 pm
tienhung wrote:Intel Compiler C++ can be integrated in MCVS and I guess that it fully supports inline assembly
https://software.intel.com/en-us/node/513428


Thanks for the suggestion. Yes, I think 'icc' does support inline assembly for x64 and it's likely that it wouldn't need the inline assembly hack in the first place.

Using 'icc' is not possible in my project. A working solution is to use MKL with "EIGEN_USE_MKL_ALL" which solves all the performance issues. I prefer to avoid MKL because of the 50+MB of dll's do distribute, the proprietary license and the more complicated build setup.

I wanted to investigate if it's possible to come close to MKL performance directly in Eigen with the standard compilers. If this is not possible, I think I'll take the MKL option.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: partialPivLu performance

Mon May 09, 2016 10:29 pm
Alright, I'm running out of idea on this issue. Maybe you could give a try to revision bb9fc0721496c (e.g., run: hg up bb9fc0721496c) for which the kernel code is slightly simpler, or maybe add the "register" keyword to the declaration of the variables C0-C11, A0, A1, A2, and B_0 to see if that helps.


Bookmarks



Who is online

Registered users: Bing [Bot], Evergrowing, Google [Bot], rockscient