2015-10-03 6 views
6

MSVC 2013 परम डब्ल्यू/अद्यतन 4समस्या निवारण ऑटो vectorize कारण '1200'

समझने नहीं क्यों मैं इस प्रतीत होता है सरल उदाहरण

जानकारी C5002 पर इस त्रुटि हो रही है: पाश कारण की वजह से '1200' vectorized नहीं

जो

1200 लूप शामिल पाश-ले गए डेटा dependences

मैं नहीं दिख रहा है कि कैसे एल की पुनरावृत्तियों ओओपी एक दूसरे के साथ हस्तक्षेप कर सकता है।

__declspec(align(16)) class PhysicsSystem 
{ 
public: 
    static const int32_t MaxEntities = 65535; 

    __declspec(align(16)) struct VectorizedXYZ 
    { 
     double  mX[ MaxEntities ]; 
     double  mY[ MaxEntities ]; 
     double  mZ[ MaxEntities ]; 

     VectorizedXYZ() 
     { 
      memset(mX, 0, sizeof(mX)); 
      memset(mY, 0, sizeof(mY)); 
      memset(mZ, 0, sizeof(mZ)); 
     } 
    }; 

    void Update(double dt) 
    { 
     for (int32_t i = 0; i < MaxEntities; ++i) <== 1200 
     { 
      mTmp.mX[ i ] = mPos.mX[ i ] + mVel.mX[ i ] * dt; 
      mTmp.mY[ i ] = mPos.mY[ i ] + mVel.mY[ i ] * dt; 
      mTmp.mZ[ i ] = mPos.mZ[ i ] + mVel.mZ[ i ] * dt; 
     } 
    } 

private:  
    VectorizedXYZ mTmp; 
    VectorizedXYZ mPos; 
    VectorizedXYZ mVel; 
}; 

संपादित करें: http://blogs.msdn.com/b/nativeconcurrency/archive/2012/05/08/auto-vectorizer-in-visual-studio-11-rules-for-loop-body.aspx इस से आंकना "उदाहरण 1 - अजीब के ठंड से समानांतर" का एक उदाहरण होने लगते हैं, लेकिन यह काम करता है जैसे कि यह सोचता है कि सरणियों अलियासिंग है, जो मुझे puzzling है से असुरक्षित हैं।

EDIT2: यह अच्छा होगा अगर किसी कारण ऑटो vectorization इस तरह के एक मालूम होता है सरल उदाहरण पर विफल रहता है साझा कर सकता है, लेकिन कुछ समय के लिए यह संवारता के बाद, मैं बजाय का विकल्प चुना शासन काल अपने आप को लेने के लिए

void PhysicsSystem::Update(Real dt) 
{ 
    const __m128d mdt = { dt, dt }; 

    // advance by 2 since we can do 2 at a time at double precision in __m128d 
    for (size_t i = 0; i < MaxEntities; i += 2) 
    { 
     __m128d posX = _mm_load_pd(&mPos.mX[ i ]); 
     __m128d posY = _mm_load_pd(&mPos.mY[ i ]); 
     __m128d posZ = _mm_load_pd(&mPos.mZ[ i ]); 

     __m128d velX = _mm_load_pd(&mVel.mX[ i ]); 
     __m128d velY = _mm_load_pd(&mVel.mY[ i ]); 
     __m128d velZ = _mm_load_pd(&mVel.mZ[ i ]); 

     __m128d velFrameX = _mm_mul_pd(velX, mdt); 
     __m128d velFrameY = _mm_mul_pd(velY, mdt); 
     __m128d velFrameZ = _mm_mul_pd(velZ, mdt); 

     _mm_store_pd(&mPos.mX[ i ], _mm_add_pd(posX, velFrameX)); 
     _mm_store_pd(&mPos.mY[ i ], _mm_add_pd(posX, velFrameY)); 
     _mm_store_pd(&mPos.mZ[ i ], _mm_add_pd(posX, velFrameZ)); 
    } 
} 
+0

बस 2 टिप्पणियां: 1/जब से अद्यतन विधि इनलाइन है, जब मैंने इसे संकलित करने का प्रयास किया, तो कुछ भी नहीं हो रहा था जो मुझे थोड़ी देर के लिए परेशान कर रहा था; और 2/अब मैंने इसे अन-रेखांकित किया है, इंटेल कंपाइलर संस्करण 15.0.3 बस बिना किसी समस्या के वेक्टर। – Gilles

+0

धन्यवाद। और दिलचस्प। एमएसवीसी 2015 इसे – jswigart

+0

पसंद नहीं करता है, मैं निश्चित रूप से आपको पोर्टेबल वेक्टरराइजेशन (ओपनएमपी 4.0 के '#pragma omp simd' का उपयोग करके उर्फ) में देखता हूं। यह मानते हुए कि आपके पास एक कंपाइलर है जो इसका समर्थन करता है (आईसीसी 15+ करता है, मुझे विश्वास है), तो यह आपके जीवन को बहुत आसान बना देगा और आपको नियंत्रण भी देगा कि वे क्या बना रहे हैं और वेक्टर नहीं हैं। ऑटो-वेक्टरिज्ड होने के बारे में संकलक को केवल "सुझाव देने" के विरोध में। – NoseKnowsAll

उत्तर

0

सुनिश्चित करें कि आपके संकलक यह समर्थन करता है तो, लेकिन कुछ उचित vectorisation लागू करने के लिए, आप portably ऐसा कर सकते हैं नहीं:

void PhysicsSystem::Update(double dt) { 
    double *tx=mTmp.mX, *ty=mTmp.mY, *tz=mTmp.mZ; 
    double *px=mPos.mX, *py=mPos.mY, *pz=mPos.mZ; 
    double *vx=mVel.mX, *vy=mVel.mY, *vz=mVel.mZ; 
    #pragma omp simd aligned(tx, ty, tz, px, py, pz, vx, vy, vz) 
    for (int i = 0; i < MaxEntities; ++i) { 
     tx[ i ] = px[ i ] + vx[ i ] * dt; 
     ty[ i ] = py[ i ] + vy[ i ] * dt; 
     tz[ i ] = pz[ i ] + vz[ i ] * dt; 
    } 
} 

आप निर्देश के लिए OpenMP समर्थन सक्षम करने की जरूरत है तो ध्यान में रखा जाना करने के लिए।

+0

क्या बिल्ली हैक। अगर मैं वह सब करता हूं लेकिन प्रगति रेखा तो यह काम करता है। – jswigart

+0

मुझे प्रगामा के बिना भी काम करने की उम्मीद थी, लेकिन यह जांच नहीं सका क्योंकि मेरे पास आपके कंपाइलर नहीं हैं .... बात यह है कि, मुझे लगता है कि कंपाइलर 'वेक्टरिज्डएक्सजेड' के अंदर सदस्य एरे के कुछ संभावित एलियासिंग मानता है। संरचनाओं। सरल पॉइंटर्स पर वापस जाकर, आप सदस्यों के बीच लिंक तोड़ते हैं ... – Gilles

+0

शायद पॉइंटर चाल के बिना 3 अलग-अलग लूप का उपयोग करने के साथ-साथ – Gilles

संबंधित मुद्दे