New user self-registration is disabled due to spam. Please email eigen-core-team @ lists.tuxfamily.org if you need an account.
Before reporting a bug, please make sure that your Eigen version is up-to-date!
Bug 652 - Eigen won't vectorize on Intel C++ compiler with msvc 2010
Summary: Eigen won't vectorize on Intel C++ compiler with msvc 2010
Status: NEW
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - vectorization (show other bugs)
Version: 3.2
Hardware: All All
: Normal Unknown
Assignee: Nobody
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-08-28 19:55 UTC by Duc Thang Ho
Modified: 2013-08-28 19:55 UTC (History)
2 users (show)



Attachments
Fix vectorization for Intel Compiler (12.52 KB, application/octet-stream)
2013-08-28 19:55 UTC, Duc Thang Ho
no flags Details

Description Duc Thang Ho 2013-08-28 19:55:22 UTC
Created attachment 377 [details]
Fix vectorization for Intel Compiler

I am using Eigen 3.2 using Intel C++ Composer XE 2013 (the latest version) with MSVC 2010. I test a very simple Eigen program, which basically like this:

Eigen::VectorXf aa(LEN);
 Eigen::VectorXf bb(LEN);
for (int i =0;i<aa.size();++i){
	aa[i] = i;
	bb[i] = i;
}
aa += bb;

The program is run with /O2, /Ob1, with SSE enabled. SSE2, SSE3, SSE 4.1, SSE 4.2 and even AVX have been tested. However, the program produced the same assembly code with no SSE vectorization. After a careful investigation of Eigen source code, I found the problem in the following lines in Eigen/Core

#ifdef _MSC_VER
  #include <malloc.h> // for _aligned_malloc -- need it regardless of whether vectorization is enabled
  #if (_MSC_VER >= 1500) // 2008 or later
    // Remember that usage of defined() in a #define is undefined by the standard.
    // a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
    #if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64)
      #define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
    #endif
  #endif
#else
  // Remember that usage of defined() in a #define is undefined by the standard
  #if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) )
    #define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
  #endif
#endif

#ifndef EIGEN_DONT_VECTORIZE

  #if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)

    // Defines symbols for compile-time detection of which instructions are
    // used.
    // EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
    #define EIGEN_VECTORIZE
    #define EIGEN_VECTORIZE_SSE
    #define EIGEN_VECTORIZE_SSE2
......


The problem is Eigen assumed that only MSVC defines _MSC_VER and all other compilers do not. The fact is Intel C++ also defines _MSC_VER (but not _M_IX86_FP). As a result, on Intel C++ compiler, the macro EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC will never be defined as expected (and neither is EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC). Therefore, none of the EIGEN_VECTORIZE* macros necessary for vectorization are defined. A very simple fix that I have used is to replace the line (see attachment)

 #if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)

with  

#if defined(__INTEL_COMPILER) || defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)

I suspect that every other versions of Eigen also suffer from this bug. Please acknowledge and fix

Note You need to log in before you can comment on or make changes to this bug.