various minor updates in the benchmark suite like non inlining
of some functions as well as the experimental C code used to design
efficient eigen's matrix vector products.
diff --git a/bench/btl/CMakeLists.txt b/bench/btl/CMakeLists.txt
index 17931f9..600fc38 100644
--- a/bench/btl/CMakeLists.txt
+++ b/bench/btl/CMakeLists.txt
@@ -46,8 +46,6 @@
 
   OPTION(BUILD_${targetname} "Build benchmark ${targetname}" ${_last_var})
 
-  message(STATUS ${targetname} " : " ${ARGN} " => " ${_sources} " => " ${_last_var})
-
   IF(BUILD_${targetname})
     ADD_EXECUTABLE(${targetname} ${_sources})
     ADD_TEST(${targetname} "${targetname}")
diff --git a/bench/btl/actions/action_matrix_vector_product.hh b/bench/btl/actions/action_matrix_vector_product.hh
index ee9110d..7e490ab 100644
--- a/bench/btl/actions/action_matrix_vector_product.hh
+++ b/bench/btl/actions/action_matrix_vector_product.hh
@@ -35,7 +35,7 @@
 
   // Ctor
 
-  Action_matrix_vector_product( int size ):_size(size)
+  BTL_DONT_INLINE Action_matrix_vector_product( int size ):_size(size)
   {
     MESSAGE("Action_matrix_vector_product Ctor");
 
@@ -68,7 +68,7 @@
 
   // Dtor
 
-  ~Action_matrix_vector_product( void ){
+  BTL_DONT_INLINE ~Action_matrix_vector_product( void ){
 
     MESSAGE("Action_matrix_vector_product Dtor");
 
@@ -95,7 +95,7 @@
     return 2.0*_size*_size;
   }
 
-  inline void initialize( void ){
+  BTL_DONT_INLINE  void initialize( void ){
 
     Interface::copy_matrix(A_ref,A,_size);
     Interface::copy_vector(B_ref,B,_size);
@@ -103,13 +103,13 @@
 
   }
 
-  inline void calculate( void ) {
-
+  BTL_DONT_INLINE void calculate( void ) {
+      asm("#begin matrix_vector_product");
       Interface::matrix_vector_product(A,B,X,_size);
-
+      asm("#end matrix_vector_product");
   }
 
-  void check_result( void ){
+  BTL_DONT_INLINE void check_result( void ){
 
     // calculation check
 
@@ -120,9 +120,9 @@
     typename Interface::real_type error=
       STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);
 
-    if (error>1.e-6){
+    if (error>1.e-5){
       INFOS("WRONG CALCULATION...residual=" << error);
-      exit(0);
+//       exit(0);
     }
 
   }
diff --git a/bench/btl/data/order_lib b/bench/btl/data/order_lib
index 5ea998a..ccbaab1 100644
--- a/bench/btl/data/order_lib
+++ b/bench/btl/data/order_lib
@@ -1,8 +1,11 @@
+eigen2_SSE
 eigen2
-C_BLAS
+INTEL_MKL
+ATLAS
 STL
 C
 gmm
+mtl4
 ublas
 blitz
 F77
diff --git a/bench/btl/generic_bench/bench.hh b/bench/btl/generic_bench/bench.hh
index 484b526..cace269 100644
--- a/bench/btl/generic_bench/bench.hh
+++ b/bench/btl/generic_bench/bench.hh
@@ -36,11 +36,13 @@
 using namespace std;
 
 template <template<class> class Perf_Analyzer, class Action>
-void bench( int size_min, int size_max, int nb_point )
+BTL_DONT_INLINE void bench( int size_min, int size_max, int nb_point )
 {
   if (BtlConfig::skipAction(Action::name()))
     return;
 
+  BTL_DISABLE_SSE_EXCEPTIONS();
+
   string filename="bench_"+Action::name()+".dat";
 
   INFOS("starting " <<filename);
@@ -76,7 +78,7 @@
 // default Perf Analyzer
 
 template <class Action>
-void bench( int size_min, int size_max, int nb_point ){
+BTL_DONT_INLINE void bench( int size_min, int size_max, int nb_point ){
 
   // if the rdtsc is not available :
   bench<Portable_Perf_Analyzer,Action>(size_min,size_max,nb_point);
diff --git a/bench/btl/generic_bench/bench_parameter.hh b/bench/btl/generic_bench/bench_parameter.hh
index e4e145e..e2db997 100644
--- a/bench/btl/generic_bench/bench_parameter.hh
+++ b/bench/btl/generic_bench/bench_parameter.hh
@@ -48,6 +48,6 @@
 #define DEFAULT_NB_SAMPLE 1000
 
 // how many times we run a single bench (keep the best perf)
-#define NB_TRIES 4
+#define NB_TRIES 3
 
 #endif
diff --git a/bench/btl/generic_bench/btl.hh b/bench/btl/generic_bench/btl.hh
index 5b561b6..7847024 100644
--- a/bench/btl/generic_bench/btl.hh
+++ b/bench/btl/generic_bench/btl.hh
@@ -26,6 +26,31 @@
 #include <string>
 #include "utilities.h"
 
+#if (defined __GNUC__)
+#define BTL_ALWAYS_INLINE __attribute__((always_inline)) inline
+#else
+#define BTL_ALWAYS_INLINE inline
+#endif
+
+#if (defined __GNUC__)
+#define BTL_DONT_INLINE __attribute__((noinline))
+#else
+#define BTL_DONT_INLINE
+#endif
+
+#ifndef __INTEL_COMPILER
+#define BTL_DISABLE_SSE_EXCEPTIONS()  { \
+  int aux; \
+  asm( \
+  "stmxcsr   %[aux]           \n\t" \
+  "orl       $32832, %[aux]   \n\t" \
+  "ldmxcsr   %[aux]           \n\t" \
+  : : [aux] "m" (aux)); \
+}
+#else
+#define DISABLE_SSE_EXCEPTIONS()
+#endif
+
 /** Enhanced std::string
 */
 class BtlString : public std::string
@@ -161,13 +186,14 @@
         }
       }
     }
+
+    BTL_DISABLE_SSE_EXCEPTIONS();
   }
 
-  static bool skipAction(const std::string& name)
+  BTL_DONT_INLINE static bool skipAction(const std::string& name)
   {
     if (Instance.m_runSingleAction)
     {
-      std::cout << "Instance.m_singleActionName = " << Instance.m_singleActionName << "\n";
       return !BtlString(name).contains(Instance.m_singleActionName);
     }
 
diff --git a/bench/btl/generic_bench/init/init_matrix.hh b/bench/btl/generic_bench/init/init_matrix.hh
index 27f8b42..6b57504 100644
--- a/bench/btl/generic_bench/init/init_matrix.hh
+++ b/bench/btl/generic_bench/init/init_matrix.hh
@@ -1,14 +1,14 @@
 //=====================================================
 // File   :  init_matrix.hh
-// Author :  L. Plagne <laurent.plagne@edf.fr)>        
+// Author :  L. Plagne <laurent.plagne@edf.fr)>
 // Copyright (C) EDF R&D,  lun sep 30 14:23:19 CEST 2002
 //=====================================================
-// 
+//
 // This program is free software; you can redistribute it and/or
 // modify it under the terms of the GNU General Public License
 // as published by the Free Software Foundation; either version 2
 // of the License, or (at your option) any later version.
-// 
+//
 // This program is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -16,7 +16,7 @@
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// 
+//
 #ifndef INIT_MATRIX_HH
 #define INIT_MATRIX_HH
 
@@ -25,7 +25,7 @@
 //            [] operator for setting element
 //            value_type defined
 template<double init_function(int,int), class Vector>
-void init_row(Vector & X, int size, int row){
+BTL_DONT_INLINE void init_row(Vector & X, int size, int row){
 
   X.resize(size);
 
@@ -40,14 +40,14 @@
 //            resize() method
 //            [] operator for setting rows
 template<double init_function(int,int),class Vector>
-void init_matrix(Vector &  A, int size){
+BTL_DONT_INLINE void init_matrix(Vector &  A, int size){
 
   A.resize(size);
   for (int row=0; row<A.size() ; row++){
     init_row<init_function>(A[row],size,row);
   }
-  
-  
+
+
 }
 
 #endif
diff --git a/bench/btl/generic_bench/static/bench_static.hh b/bench/btl/generic_bench/static/bench_static.hh
index 0bc0d44..cdb645f 100644
--- a/bench/btl/generic_bench/static/bench_static.hh
+++ b/bench/btl/generic_bench/static/bench_static.hh
@@ -34,7 +34,7 @@
 
 
 template <template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface>
-void bench_static(void)
+BTL_DONT_INLINE  void bench_static(void)
 {
   if (BtlConfig::skipAction(Action<Interface<REAL_TYPE,10> >::name()))
     return;
@@ -55,7 +55,7 @@
 
 // default Perf Analyzer
 template <template<class> class Action, template<class,int> class Interface>
-void bench_static(void)
+BTL_DONT_INLINE  void bench_static(void)
 {
   bench_static<Portable_Perf_Analyzer,Action,Interface>();
   //bench_static<Mixed_Perf_Analyzer,Action,Interface>();
diff --git a/bench/btl/generic_bench/timers/portable_perf_analyzer.hh b/bench/btl/generic_bench/timers/portable_perf_analyzer.hh
index 709f0de..d716154 100644
--- a/bench/btl/generic_bench/timers/portable_perf_analyzer.hh
+++ b/bench/btl/generic_bench/timers/portable_perf_analyzer.hh
@@ -40,7 +40,7 @@
 
 
 
-  inline double eval_mflops(int size)
+  BTL_DONT_INLINE  double eval_mflops(int size)
   {
     Action action(size);
 
@@ -70,7 +70,7 @@
     return action.nb_op_base()/(time_action*1000000.0);
   }
 
-  double time_calculate(Action & action)
+  BTL_DONT_INLINE double time_calculate(Action & action)
   {
     // time measurement
     _chronos.start();
diff --git a/bench/btl/libs/C/CMakeLists.txt b/bench/btl/libs/C/CMakeLists.txt
index d3d2312..2bce21e 100644
--- a/bench/btl/libs/C/CMakeLists.txt
+++ b/bench/btl/libs/C/CMakeLists.txt
@@ -1,2 +1,3 @@
 include_directories(${PROJECT_SOURCE_DIR}/libs/f77)
 btl_add_bench(btl_C main.cpp)
+# set_target_properties(btl_C PROPERTIES COMPILE_FLAGS "-fpeel-loops")
\ No newline at end of file
diff --git a/bench/btl/libs/eigen2/eigen2_interface.hh b/bench/btl/libs/eigen2/eigen2_interface.hh
index 8c4270e..fa7f759 100644
--- a/bench/btl/libs/eigen2/eigen2_interface.hh
+++ b/bench/btl/libs/eigen2/eigen2_interface.hh
@@ -20,6 +20,7 @@
 
 #include <Eigen/Core>
 #include <vector>
+#include "btl.hh"
 
 using namespace Eigen;
 
@@ -52,7 +53,7 @@
 
   static void free_vector(gene_vector & B) {}
 
-  static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
+  static BTL_DONT_INLINE void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){
     A.resize(A_stl[0].size(), A_stl.size());
 
     for (int j=0; j<A_stl.size() ; j++){
@@ -62,7 +63,7 @@
     }
   }
 
-  static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){
+  static BTL_DONT_INLINE  void vector_from_stl(gene_vector & B, stl_vector & B_stl){
     B.resize(B_stl.size(),1);
 
     for (int i=0; i<B_stl.size() ; i++){
@@ -70,13 +71,13 @@
     }
   }
 
-  static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){
+  static BTL_DONT_INLINE  void vector_to_stl(gene_vector & B, stl_vector & B_stl){
     for (int i=0; i<B_stl.size() ; i++){
       B_stl[i] = B.coeff(i);
     }
   }
 
-  static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
+  static BTL_DONT_INLINE  void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){
     int N=A_stl.size();
 
     for (int j=0;j<N;j++){
@@ -103,7 +104,7 @@
     X = (A*A.transpose()).lazy();
   }
 
-  static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){
+  static inline void matrix_vector_product(const gene_matrix &  __restrict__  A, const gene_vector & __restrict__ B, gene_vector &  __restrict__ X, int N){
     X = (A*B).lazy();
   }
 
diff --git a/bench/btl/libs/eigen2/main.cpp b/bench/btl/libs/eigen2/main.cpp
index 7f96c84..f38dfcc 100644
--- a/bench/btl/libs/eigen2/main.cpp
+++ b/bench/btl/libs/eigen2/main.cpp
@@ -32,8 +32,8 @@
 {
 
   bench<Action_matrix_vector_product<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
-  bench<Action_atv_product<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
-  bench<Action_axpy<eigen2_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
+//   bench<Action_atv_product<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);
+//   bench<Action_axpy<eigen2_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);
 //   bench<Action_matrix_matrix_product<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
 //   bench<Action_ata_product<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
 //   bench<Action_aat_product<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);
diff --git a/bench/btl/libs/hand_vec/hand_vec_interface.hh b/bench/btl/libs/hand_vec/hand_vec_interface.hh
index 5291aac..538c03b 100755
--- a/bench/btl/libs/hand_vec/hand_vec_interface.hh
+++ b/bench/btl/libs/hand_vec/hand_vec_interface.hh
@@ -68,139 +68,476 @@
     #endif
   }
 
-  static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)
+static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)
   {
+    asm("#begin matrix_vector_product");
     int AN = (N/PacketSize)*PacketSize;
+    int ANP = (AN/(4*PacketSize))*4*PacketSize;
+    int bound = (N/4)*4;
     for (int i=0;i<N;i++)
       X[i] = 0;
-    for (int i=0;i<N;i++)
+
+    for (int i=0;i<bound;i+=4)
     {
-      real tmp = B[i];
-      Packet ptmp = ei_pset1(tmp);
-      int iN = i*N;
+      real tmp0 = B[i];
+      Packet ptmp0 = ei_pset1(tmp0);
+      real tmp1 = B[i+1];
+      Packet ptmp1 = ei_pset1(tmp1);
+      real tmp2 = B[i+2];
+      Packet ptmp2 = ei_pset1(tmp2);
+      real tmp3 = B[i+3];
+      Packet ptmp3 = ei_pset1(tmp3);
+      int iN0 = i*N;
+      int iN1 = (i+1)*N;
+      int iN2 = (i+2)*N;
+      int iN3 = (i+3)*N;
       if (AN>0)
       {
-        bool aligned = (iN % PacketSize) == 0;
-        if (aligned)
+//         int aligned0 = (iN0 % PacketSize);
+        int aligned1 = (iN1 % PacketSize);
+
+        if (aligned1==0)
         {
-          #ifdef PEELING
-          int ANP = (AN/(8*PacketSize))*8*PacketSize;
-          for (int j = 0;j<ANP;j+=PacketSize*8)
-          {
-            ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_pload(&A[j+iN]))));
-            ei_pstore(&X[j+PacketSize], ei_padd(ei_pload(&X[j+PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+PacketSize+iN]))));
-            ei_pstore(&X[j+2*PacketSize], ei_padd(ei_pload(&X[j+2*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+2*PacketSize+iN]))));
-            ei_pstore(&X[j+3*PacketSize], ei_padd(ei_pload(&X[j+3*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+3*PacketSize+iN]))));
-            ei_pstore(&X[j+4*PacketSize], ei_padd(ei_pload(&X[j+4*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+4*PacketSize+iN]))));
-            ei_pstore(&X[j+5*PacketSize], ei_padd(ei_pload(&X[j+5*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+5*PacketSize+iN]))));
-            ei_pstore(&X[j+6*PacketSize], ei_padd(ei_pload(&X[j+6*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+6*PacketSize+iN]))));
-            ei_pstore(&X[j+7*PacketSize], ei_padd(ei_pload(&X[j+7*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+7*PacketSize+iN]))));
-          }
-          for (int j = ANP;j<AN;j+=PacketSize)
-            ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_pload(&A[j+iN]))));
-          #else
           for (int j = 0;j<AN;j+=PacketSize)
-            ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_pload(&A[j+iN]))));
-          #endif
+          {
+            ei_pstore(&X[j],
+              ei_padd(ei_pload(&X[j]),
+                ei_padd(
+                  ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+iN0])),ei_pmul(ptmp1,ei_pload(&A[j+iN1]))),
+                  ei_padd(ei_pmul(ptmp2,ei_pload(&A[j+iN2])),ei_pmul(ptmp3,ei_pload(&A[j+iN3]))) )));
+          }
+        }
+        else if (aligned1==2)
+        {
+          for (int j = 0;j<AN;j+=PacketSize)
+          {
+            ei_pstore(&X[j],
+              ei_padd(ei_pload(&X[j]),
+                ei_padd(
+                  ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+iN0])),ei_pmul(ptmp1,ei_ploadu(&A[j+iN1]))),
+                  ei_padd(ei_pmul(ptmp2,ei_pload(&A[j+iN2])),ei_pmul(ptmp3,ei_ploadu(&A[j+iN3]))) )));
+          }
         }
         else
         {
-          #ifdef PEELING
-          int ANP = (AN/(8*PacketSize))*8*PacketSize;
-          for (int j = 0;j<ANP;j+=PacketSize*8)
+          for (int j = 0;j<ANP;j+=4*PacketSize)
           {
-            ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_ploadu(&A[j+iN]))));
-            ei_pstore(&X[j+PacketSize], ei_padd(ei_pload(&X[j+PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+PacketSize+iN]))));
-            ei_pstore(&X[j+2*PacketSize], ei_padd(ei_pload(&X[j+2*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+2*PacketSize+iN]))));
-            ei_pstore(&X[j+3*PacketSize], ei_padd(ei_pload(&X[j+3*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+3*PacketSize+iN]))));
-            ei_pstore(&X[j+4*PacketSize], ei_padd(ei_pload(&X[j+4*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+4*PacketSize+iN]))));
-            ei_pstore(&X[j+5*PacketSize], ei_padd(ei_pload(&X[j+5*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+5*PacketSize+iN]))));
-            ei_pstore(&X[j+6*PacketSize], ei_padd(ei_pload(&X[j+6*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+6*PacketSize+iN]))));
-            ei_pstore(&X[j+7*PacketSize], ei_padd(ei_pload(&X[j+7*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+7*PacketSize+iN]))));
+            ei_pstore(&X[j],
+              ei_padd(ei_pload(&X[j]),
+                ei_padd(
+                  ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+iN0])),ei_pmul(ptmp1,ei_ploadu(&A[j+iN1]))),
+                  ei_padd(ei_pmul(ptmp2,ei_ploadu(&A[j+iN2])),ei_pmul(ptmp3,ei_ploadu(&A[j+iN3]))) )));
+
+            ei_pstore(&X[j+PacketSize],
+              ei_padd(ei_pload(&X[j+PacketSize]),
+                ei_padd(
+                  ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+PacketSize+iN0])),ei_pmul(ptmp1,ei_ploadu(&A[j+PacketSize+iN1]))),
+                  ei_padd(ei_pmul(ptmp2,ei_ploadu(&A[j+PacketSize+iN2])),ei_pmul(ptmp3,ei_ploadu(&A[j+PacketSize+iN3]))) )));
+
+            ei_pstore(&X[j+2*PacketSize],
+              ei_padd(ei_pload(&X[j+2*PacketSize]),
+                ei_padd(
+                  ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+2*PacketSize+iN0])),ei_pmul(ptmp1,ei_ploadu(&A[j+2*PacketSize+iN1]))),
+                  ei_padd(ei_pmul(ptmp2,ei_ploadu(&A[j+2*PacketSize+iN2])),ei_pmul(ptmp3,ei_ploadu(&A[j+2*PacketSize+iN3]))) )));
+
+            ei_pstore(&X[j+3*PacketSize],
+              ei_padd(ei_pload(&X[j+3*PacketSize]),
+                ei_padd(
+                  ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+3*PacketSize+iN0])),ei_pmul(ptmp1,ei_ploadu(&A[j+3*PacketSize+iN1]))),
+                  ei_padd(ei_pmul(ptmp2,ei_ploadu(&A[j+3*PacketSize+iN2])),ei_pmul(ptmp3,ei_ploadu(&A[j+3*PacketSize+iN3]))) )));
+
           }
           for (int j = ANP;j<AN;j+=PacketSize)
-            ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_ploadu(&A[j+iN]))));
-          #else
-          for (int j = 0;j<AN;j+=PacketSize)
-            ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_ploadu(&A[j+iN]))));
-          #endif
+            ei_pstore(&X[j],
+              ei_padd(ei_pload(&X[j]),
+                ei_padd(
+                  ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+iN0])),ei_pmul(ptmp1,ei_ploadu(&A[j+iN1]))),
+                  ei_padd(ei_pmul(ptmp2,ei_ploadu(&A[j+iN2])),ei_pmul(ptmp3,ei_ploadu(&A[j+iN3]))) )));
         }
       }
       // process remaining scalars
       for (int j=AN;j<N;j++)
-        X[j] += tmp * A[j+iN];
+        X[j] += tmp0 * A[j+iN0] + tmp1 * A[j+iN1];
+    }
+    for (int i=bound;i<N;i++)
+    {
+      real tmp0 = B[i];
+      Packet ptmp0 = ei_pset1(tmp0);
+      int iN0 = i*N;
+      if (AN>0)
+      {
+        bool aligned0 = (iN0 % PacketSize) == 0;
+        if (aligned0)
+          for (int j = 0;j<AN;j+=PacketSize)
+            ei_pstore(&X[j], ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+iN0])),ei_pload(&X[j])));
+        else
+          for (int j = 0;j<AN;j+=PacketSize)
+            ei_pstore(&X[j], ei_padd(ei_pmul(ptmp0,ei_ploadu(&A[j+iN0])),ei_pload(&X[j])));
+      }
+      // process remaining scalars
+      for (int j=AN;j<N;j++)
+        X[j] += tmp0 * A[j+iN0];
+    }
+    asm("#end matrix_vector_product");
+  }
+
+//   static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)
+//   {
+//     asm("#begin matrix_vector_product");
+//     int AN = (N/PacketSize)*PacketSize;
+//     for (int i=0;i<N;i++)
+//       X[i] = 0;
+//
+//     for (int i=0;i<N;i+=2)
+//     {
+//       real tmp0 = B[i];
+//       Packet ptmp0 = ei_pset1(tmp0);
+//       real tmp1 = B[i+1];
+//       Packet ptmp1 = ei_pset1(tmp1);
+//       int iN0 = i*N;
+//       int iN1 = (i+1)*N;
+//       if (AN>0)
+//       {
+//         bool aligned0 = (iN0 % PacketSize) == 0;
+//         bool aligned1 = (iN1 % PacketSize) == 0;
+//
+//         if (aligned0 && aligned1)
+//         {
+//           for (int j = 0;j<AN;j+=PacketSize)
+//           {
+//             ei_pstore(&X[j],
+//               ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+iN0])),
+//               ei_padd(ei_pmul(ptmp1,ei_pload(&A[j+iN1])),ei_pload(&X[j]))));
+//           }
+//         }
+//         else if (aligned0)
+//         {
+//           for (int j = 0;j<AN;j+=PacketSize)
+//           {
+//             ei_pstore(&X[j],
+//               ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+iN0])),
+//               ei_padd(ei_pmul(ptmp1,ei_ploadu(&A[j+iN1])),ei_pload(&X[j]))));
+//           }
+//         }
+//         else if (aligned1)
+//         {
+//           for (int j = 0;j<AN;j+=PacketSize)
+//           {
+//             ei_pstore(&X[j],
+//               ei_padd(ei_pmul(ptmp0,ei_ploadu(&A[j+iN0])),
+//               ei_padd(ei_pmul(ptmp1,ei_pload(&A[j+iN1])),ei_pload(&X[j]))));
+//           }
+//         }
+//         else
+//         {
+//           int ANP = (AN/(4*PacketSize))*4*PacketSize;
+//           for (int j = 0;j<ANP;j+=4*PacketSize)
+//           {
+//             ei_pstore(&X[j],
+//               ei_padd(ei_pmul(ptmp0,ei_ploadu(&A[j+iN0])),
+//               ei_padd(ei_pmul(ptmp1,ei_ploadu(&A[j+iN1])),ei_pload(&X[j]))));
+//
+//             ei_pstore(&X[j+PacketSize],
+//               ei_padd(ei_pmul(ptmp0,ei_ploadu(&A[j+PacketSize+iN0])),
+//               ei_padd(ei_pmul(ptmp1,ei_ploadu(&A[j+PacketSize+iN1])),ei_pload(&X[j+PacketSize]))));
+//
+//             ei_pstore(&X[j+2*PacketSize],
+//               ei_padd(ei_pmul(ptmp0,ei_ploadu(&A[j+2*PacketSize+iN0])),
+//               ei_padd(ei_pmul(ptmp1,ei_ploadu(&A[j+2*PacketSize+iN1])),ei_pload(&X[j+2*PacketSize]))));
+//
+//             ei_pstore(&X[j+3*PacketSize],
+//               ei_padd(ei_pmul(ptmp0,ei_ploadu(&A[j+3*PacketSize+iN0])),
+//               ei_padd(ei_pmul(ptmp1,ei_ploadu(&A[j+3*PacketSize+iN1])),ei_pload(&X[j+3*PacketSize]))));
+//           }
+//           for (int j = ANP;j<AN;j+=PacketSize)
+//             ei_pstore(&X[j],
+//               ei_padd(ei_pmul(ptmp0,ei_ploadu(&A[j+iN0])),
+//               ei_padd(ei_pmul(ptmp1,ei_ploadu(&A[j+iN1])),ei_pload(&X[j]))));
+//         }
+//       }
+//       // process remaining scalars
+//       for (int j=AN;j<N;j++)
+//         X[j] += tmp0 * A[j+iN0] + tmp1 * A[j+iN1];
+//     }
+//     int remaining = (N/2)*2;
+//     for (int i=remaining;i<N;i++)
+//     {
+//       real tmp0 = B[i];
+//       Packet ptmp0 = ei_pset1(tmp0);
+//       int iN0 = i*N;
+//       if (AN>0)
+//       {
+//         bool aligned0 = (iN0 % PacketSize) == 0;
+//         if (aligned0)
+//           for (int j = 0;j<AN;j+=PacketSize)
+//             ei_pstore(&X[j], ei_padd(ei_pmul(ptmp0,ei_pload(&A[j+iN0])),ei_pload(&X[j])));
+//         else
+//           for (int j = 0;j<AN;j+=PacketSize)
+//             ei_pstore(&X[j], ei_padd(ei_pmul(ptmp0,ei_ploadu(&A[j+iN0])),ei_pload(&X[j])));
+//       }
+//       // process remaining scalars
+//       for (int j=AN;j<N;j++)
+//         X[j] += tmp0 * A[j+iN0];
+//     }
+//     asm("#end matrix_vector_product");
+//   }
+
+//   static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)
+//   {
+//     asm("#begin matrix_vector_product");
+//     int AN = (N/PacketSize)*PacketSize;
+//     for (int i=0;i<N;i++)
+//       X[i] = 0;
+//     for (int i=0;i<N;i++)
+//     {
+//       real tmp = B[i];
+//       Packet ptmp = ei_pset1(tmp);
+//       int iN = i*N;
+//       if (AN>0)
+//       {
+//         bool aligned = (iN % PacketSize) == 0;
+//         if (aligned)
+//         {
+//           #ifdef PEELING
+//           Packet A0, A1, A2, X0, X1, X2;
+//           int ANP = (AN/(8*PacketSize))*8*PacketSize;
+//           for (int j = 0;j<ANP;j+=PacketSize*8)
+//           {
+//             A0 = ei_pload(&A[j+iN]);
+//             X0 = ei_pload(&X[j]);
+//             A1 = ei_pload(&A[j+PacketSize+iN]);
+//             X1 = ei_pload(&X[j+PacketSize]);
+//             A2 = ei_pload(&A[j+2*PacketSize+iN]);
+//             X2 = ei_pload(&X[j+2*PacketSize]);
+//             ei_pstore(&X[j], ei_padd(X0, ei_pmul(ptmp,A0)));
+//             A0 = ei_pload(&A[j+3*PacketSize+iN]);
+//             X0 = ei_pload(&X[j+3*PacketSize]);
+//             ei_pstore(&X[j+PacketSize], ei_padd(ei_pload(&X1), ei_pmul(ptmp,A1)));
+//             A1 = ei_pload(&A[j+4*PacketSize+iN]);
+//             X1 = ei_pload(&X[j+4*PacketSize]);
+//             ei_pstore(&X[j+2*PacketSize], ei_padd(ei_pload(&X2), ei_pmul(ptmp,A2)));
+//             A2 = ei_pload(&A[j+5*PacketSize+iN]);
+//             X2 = ei_pload(&X[j+5*PacketSize]);
+//             ei_pstore(&X[j+3*PacketSize], ei_padd(ei_pload(&X0), ei_pmul(ptmp,A0)));
+//             A0 = ei_pload(&A[j+6*PacketSize+iN]);
+//             X0 = ei_pload(&X[j+6*PacketSize]);
+//             ei_pstore(&X[j+4*PacketSize], ei_padd(ei_pload(&X1), ei_pmul(ptmp,A1)));
+//             A1 = ei_pload(&A[j+7*PacketSize+iN]);
+//             X1 = ei_pload(&X[j+7*PacketSize]);
+//             ei_pstore(&X[j+5*PacketSize], ei_padd(ei_pload(&X2), ei_pmul(ptmp,A2)));
+//             ei_pstore(&X[j+6*PacketSize], ei_padd(ei_pload(&X0), ei_pmul(ptmp,A0)));
+//             ei_pstore(&X[j+7*PacketSize], ei_padd(ei_pload(&X1), ei_pmul(ptmp,A1)));
+// //
+// //             ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_pload(&A[j+iN]))));
+// //             ei_pstore(&X[j+PacketSize], ei_padd(ei_pload(&X[j+PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+PacketSize+iN]))));
+// //             ei_pstore(&X[j+2*PacketSize], ei_padd(ei_pload(&X[j+2*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+2*PacketSize+iN]))));
+// //             ei_pstore(&X[j+3*PacketSize], ei_padd(ei_pload(&X[j+3*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+3*PacketSize+iN]))));
+// //             ei_pstore(&X[j+4*PacketSize], ei_padd(ei_pload(&X[j+4*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+4*PacketSize+iN]))));
+// //             ei_pstore(&X[j+5*PacketSize], ei_padd(ei_pload(&X[j+5*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+5*PacketSize+iN]))));
+// //             ei_pstore(&X[j+6*PacketSize], ei_padd(ei_pload(&X[j+6*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+6*PacketSize+iN]))));
+// //             ei_pstore(&X[j+7*PacketSize], ei_padd(ei_pload(&X[j+7*PacketSize]), ei_pmul(ptmp,ei_pload(&A[j+7*PacketSize+iN]))));
+//           }
+//           for (int j = ANP;j<AN;j+=PacketSize)
+//             ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_pload(&A[j+iN]))));
+//           #else
+//           for (int j = 0;j<AN;j+=PacketSize)
+//             ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_pload(&A[j+iN]))));
+//           #endif
+//         }
+//         else
+//         {
+//           #ifdef PEELING
+//           int ANP = (AN/(8*PacketSize))*8*PacketSize;
+//           for (int j = 0;j<ANP;j+=PacketSize*8)
+//           {
+//             ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_ploadu(&A[j+iN]))));
+//             ei_pstore(&X[j+PacketSize], ei_padd(ei_pload(&X[j+PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+PacketSize+iN]))));
+//             ei_pstore(&X[j+2*PacketSize], ei_padd(ei_pload(&X[j+2*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+2*PacketSize+iN]))));
+//             ei_pstore(&X[j+3*PacketSize], ei_padd(ei_pload(&X[j+3*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+3*PacketSize+iN]))));
+//             ei_pstore(&X[j+4*PacketSize], ei_padd(ei_pload(&X[j+4*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+4*PacketSize+iN]))));
+//             ei_pstore(&X[j+5*PacketSize], ei_padd(ei_pload(&X[j+5*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+5*PacketSize+iN]))));
+//             ei_pstore(&X[j+6*PacketSize], ei_padd(ei_pload(&X[j+6*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+6*PacketSize+iN]))));
+//             ei_pstore(&X[j+7*PacketSize], ei_padd(ei_pload(&X[j+7*PacketSize]), ei_pmul(ptmp,ei_ploadu(&A[j+7*PacketSize+iN]))));
+//           }
+//           for (int j = ANP;j<AN;j+=PacketSize)
+//             ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_ploadu(&A[j+iN]))));
+//           #else
+//           for (int j = 0;j<AN;j+=PacketSize)
+//             ei_pstore(&X[j], ei_padd(ei_pload(&X[j]), ei_pmul(ptmp,ei_ploadu(&A[j+iN]))));
+//           #endif
+//         }
+//       }
+//       // process remaining scalars
+//       for (int j=AN;j<N;j++)
+//         X[j] += tmp * A[j+iN];
+//     }
+//     asm("#end matrix_vector_product");
+//   }
+
+    static inline void atv_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)
+  {
+    int AN = (N/PacketSize)*PacketSize;
+    int bound = (N/4)*4;
+    for (int i=0;i<bound;i+=4)
+    {
+      real tmp0 = 0;
+      Packet ptmp0 = ei_pset1(real(0));
+      real tmp1 = 0;
+      Packet ptmp1 = ei_pset1(real(0));
+      real tmp2 = 0;
+      Packet ptmp2 = ei_pset1(real(0));
+      real tmp3 = 0;
+      Packet ptmp3 = ei_pset1(real(0));
+      int iN0 = i*N;
+      int iN1 = (i+1)*N;
+      int iN2 = (i+2)*N;
+      int iN3 = (i+3)*N;
+      if (AN>0)
+      {
+        int align1 = (iN1 % PacketSize);
+        if (align1==0)
+        {
+          for (int j = 0;j<AN;j+=PacketSize)
+          {
+            Packet b = ei_pload(&B[j]);
+            ptmp0 = ei_padd(ptmp0, ei_pmul(b, ei_pload(&A[j+iN0])));
+            ptmp1 = ei_padd(ptmp1, ei_pmul(b, ei_pload(&A[j+iN1])));
+            ptmp2 = ei_padd(ptmp2, ei_pmul(b, ei_pload(&A[j+iN2])));
+            ptmp3 = ei_padd(ptmp3, ei_pmul(b, ei_pload(&A[j+iN3])));
+          }
+        }
+        else if (align1==2)
+        {
+          for (int j = 0;j<AN;j+=PacketSize)
+          {
+            Packet b = ei_pload(&B[j]);
+            ptmp0 = ei_padd(ptmp0, ei_pmul(b, ei_pload(&A[j+iN0])));
+            ptmp1 = ei_padd(ptmp1, ei_pmul(b, ei_ploadu(&A[j+iN1])));
+            ptmp2 = ei_padd(ptmp2, ei_pmul(b, ei_pload(&A[j+iN2])));
+            ptmp3 = ei_padd(ptmp3, ei_pmul(b, ei_ploadu(&A[j+iN3])));
+          }
+        }
+        else
+        {
+          for (int j = 0;j<AN;j+=PacketSize)
+          {
+            Packet b = ei_pload(&B[j]);
+            ptmp0 = ei_padd(ptmp0, ei_pmul(b, ei_pload(&A[j+iN0])));
+            ptmp1 = ei_padd(ptmp1, ei_pmul(b, ei_ploadu(&A[j+iN1])));
+            ptmp2 = ei_padd(ptmp2, ei_pmul(b, ei_ploadu(&A[j+iN2])));
+            ptmp3 = ei_padd(ptmp3, ei_pmul(b, ei_ploadu(&A[j+iN3])));
+          }
+        }
+        tmp0 = ei_predux(ptmp0);
+        tmp1 = ei_predux(ptmp1);
+        tmp2 = ei_predux(ptmp2);
+        tmp3 = ei_predux(ptmp3);
+      }
+      // process remaining scalars
+      for (int j=AN;j<N;j++)
+      {
+        tmp0 += B[j] * A[j+iN0];
+        tmp1 += B[j] * A[j+iN1];
+        tmp2 += B[j] * A[j+iN2];
+        tmp3 += B[j] * A[j+iN3];
+      }
+      X[i+0] = tmp0;
+      X[i+1] = tmp1;
+      X[i+2] = tmp2;
+      X[i+3] = tmp3;
+    }
+
+    for (int i=bound;i<N;i++)
+    {
+      real tmp0 = 0;
+      Packet ptmp0 = ei_pset1(real(0));
+      int iN0 = i*N;
+      if (AN>0)
+      {
+        if (iN0 % PacketSize==0)
+          for (int j = 0;j<AN;j+=PacketSize)
+            ptmp0 = ei_padd(ptmp0, ei_pmul(ei_pload(&B[j]), ei_pload(&A[j+iN0])));
+        else
+          for (int j = 0;j<AN;j+=PacketSize)
+            ptmp0 = ei_padd(ptmp0, ei_pmul(ei_pload(&B[j]), ei_ploadu(&A[j+iN0])));
+        tmp0 = ei_predux(ptmp0);
+      }
+      // process remaining scalars
+      for (int j=AN;j<N;j++)
+        tmp0 += B[j] * A[j+iN0];
+      X[i+0] = tmp0;
     }
   }
 
-  static inline void atv_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)
-  {
-    int AN = (N/PacketSize)*PacketSize;
-    for (int i=0;i<N;i++)
-      X[i] = 0;
-    for (int i=0;i<N;i++)
-    {
-      real tmp = 0;
-      Packet ptmp = ei_pset1(real(0));
-      int iN = i*N;
-      if (AN>0)
-      {
-        bool aligned = (iN % PacketSize) == 0;
-        if (aligned)
-        {
-          #ifdef PEELING
-          int ANP = (AN/(8*PacketSize))*8*PacketSize;
-          for (int j = 0;j<ANP;j+=PacketSize*8)
-          {
-            ptmp =
-              ei_padd(ei_pmul(ei_pload(&B[j]), ei_pload(&A[j+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+PacketSize]), ei_pload(&A[j+PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+2*PacketSize]), ei_pload(&A[j+2*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+3*PacketSize]), ei_pload(&A[j+3*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+4*PacketSize]), ei_pload(&A[j+4*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+5*PacketSize]), ei_pload(&A[j+5*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+6*PacketSize]), ei_pload(&A[j+6*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+7*PacketSize]), ei_pload(&A[j+7*PacketSize+iN])),
-              ptmp))))))));
-          }
-          for (int j = ANP;j<AN;j+=PacketSize)
-            ptmp = ei_padd(ptmp, ei_pmul(ei_pload(&B[j]), ei_pload(&A[j+iN])));
-          #else
-          for (int j = 0;j<AN;j+=PacketSize)
-            ptmp = ei_padd(ptmp, ei_pmul(ei_pload(&B[j]), ei_pload(&A[j+iN])));
-          #endif
-        }
-        else
-        {
-          #ifdef PEELING
-          int ANP = (AN/(8*PacketSize))*8*PacketSize;
-          for (int j = 0;j<ANP;j+=PacketSize*8)
-          {
-            ptmp =
-              ei_padd(ei_pmul(ei_pload(&B[j]), ei_ploadu(&A[j+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+PacketSize]), ei_ploadu(&A[j+PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+2*PacketSize]), ei_ploadu(&A[j+2*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+3*PacketSize]), ei_ploadu(&A[j+3*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+4*PacketSize]), ei_ploadu(&A[j+4*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+5*PacketSize]), ei_ploadu(&A[j+5*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+6*PacketSize]), ei_ploadu(&A[j+6*PacketSize+iN])),
-              ei_padd(ei_pmul(ei_pload(&B[j+7*PacketSize]), ei_ploadu(&A[j+7*PacketSize+iN])),
-              ptmp))))))));
-          }
-          for (int j = ANP;j<AN;j+=PacketSize)
-            ptmp = ei_padd(ptmp, ei_pmul(ei_pload(&B[j]), ei_ploadu(&A[j+iN])));
-          #else
-          for (int j = 0;j<AN;j+=PacketSize)
-            ptmp = ei_padd(ptmp, ei_pmul(ei_pload(&B[j]), ei_ploadu(&A[j+iN])));
-          #endif
-        }
-        tmp = ei_predux(ptmp);
-      }
-      // process remaining scalars
-      for (int j=AN;j<N;j++)
-        tmp += B[j] * A[j+iN];
-      X[i] = tmp;
-    }
-  }
+//   static inline void atv_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)
+//   {
+//     int AN = (N/PacketSize)*PacketSize;
+//     for (int i=0;i<N;i++)
+//       X[i] = 0;
+//     for (int i=0;i<N;i++)
+//     {
+//       real tmp = 0;
+//       Packet ptmp = ei_pset1(real(0));
+//       int iN = i*N;
+//       if (AN>0)
+//       {
+//         bool aligned = (iN % PacketSize) == 0;
+//         if (aligned)
+//         {
+//           #ifdef PEELING
+//           int ANP = (AN/(8*PacketSize))*8*PacketSize;
+//           for (int j = 0;j<ANP;j+=PacketSize*8)
+//           {
+//             ptmp =
+//               ei_padd(ei_pmul(ei_pload(&B[j]), ei_pload(&A[j+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+PacketSize]), ei_pload(&A[j+PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+2*PacketSize]), ei_pload(&A[j+2*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+3*PacketSize]), ei_pload(&A[j+3*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+4*PacketSize]), ei_pload(&A[j+4*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+5*PacketSize]), ei_pload(&A[j+5*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+6*PacketSize]), ei_pload(&A[j+6*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+7*PacketSize]), ei_pload(&A[j+7*PacketSize+iN])),
+//               ptmp))))))));
+//           }
+//           for (int j = ANP;j<AN;j+=PacketSize)
+//             ptmp = ei_padd(ptmp, ei_pmul(ei_pload(&B[j]), ei_pload(&A[j+iN])));
+//           #else
+//           for (int j = 0;j<AN;j+=PacketSize)
+//             ptmp = ei_padd(ptmp, ei_pmul(ei_pload(&B[j]), ei_pload(&A[j+iN])));
+//           #endif
+//         }
+//         else
+//         {
+//           #ifdef PEELING
+//           int ANP = (AN/(8*PacketSize))*8*PacketSize;
+//           for (int j = 0;j<ANP;j+=PacketSize*8)
+//           {
+//             ptmp =
+//               ei_padd(ei_pmul(ei_pload(&B[j]), ei_ploadu(&A[j+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+PacketSize]), ei_ploadu(&A[j+PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+2*PacketSize]), ei_ploadu(&A[j+2*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+3*PacketSize]), ei_ploadu(&A[j+3*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+4*PacketSize]), ei_ploadu(&A[j+4*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+5*PacketSize]), ei_ploadu(&A[j+5*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+6*PacketSize]), ei_ploadu(&A[j+6*PacketSize+iN])),
+//               ei_padd(ei_pmul(ei_pload(&B[j+7*PacketSize]), ei_ploadu(&A[j+7*PacketSize+iN])),
+//               ptmp))))))));
+//           }
+//           for (int j = ANP;j<AN;j+=PacketSize)
+//             ptmp = ei_padd(ptmp, ei_pmul(ei_pload(&B[j]), ei_ploadu(&A[j+iN])));
+//           #else
+//           for (int j = 0;j<AN;j+=PacketSize)
+//             ptmp = ei_padd(ptmp, ei_pmul(ei_pload(&B[j]), ei_ploadu(&A[j+iN])));
+//           #endif
+//         }
+//         tmp = ei_predux(ptmp);
+//       }
+//       // process remaining scalars
+//       for (int j=AN;j<N;j++)
+//         tmp += B[j] * A[j+iN];
+//       X[i] = tmp;
+//     }
+//   }
 
   static inline void axpy(real coef, const gene_vector & X, gene_vector & Y, int N){
     int AN = (N/PacketSize)*PacketSize;