MSVC 2013 ultimo w/Update 4Risoluzione dei problemi ragione auto vectorize '1200'
Non capire perché sto ottenendo questo errore su questo apparentemente semplice esempio
informazioni C5002: ciclo non vettorializzare a causa di motivi '1200'
che è
1200 loop contiene dipendenze dati di loop-trasportato
non vedo come le iterazioni della l oop potrebbe interferire l'uno con l'altro.
__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;
};
Edit: A giudicare dalla http://blogs.msdn.com/b/nativeconcurrency/archive/2012/05/08/auto-vectorizer-in-visual-studio-11-rules-for-loop-body.aspx questo sembrerebbe essere un esempio di "Esempio 1 - imbarazzante parallelo", ma si comporta come pensa gli array non sono sicure da aliasing, che è sconcertante per me.
Edit2: Sarebbe bello se qualcuno potesse condividere i motivi per cui la vettorializzazione automatica non riesce in un apparentemente semplice esempio così, ma dopo armeggiare con esso per un po ', ho optato invece di prendere le redini me
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));
}
}
Solo 2 osservazioni: 1/poiché il metodo di aggiornamento è in linea, quando ho provato a compilare questo, non è successo nulla che mi abbia perplesso per un po '; e 2/ora che l'ho annullato, la versione 15.0.3 del compilatore Intel si limita a vettorializzare senza alcun problema. – Gilles
Grazie. E interessante. MSVC 2015 non gli piace né – jswigart
Ti suggerirei sicuramente di esaminare la vettorizzazione portatile (nota anche con il comando #pragma omp simd di OpenMP 4.0). Supponendo che tu abbia un compilatore che lo supporta (icc 15+ fa, credo), allora entrambi renderanno la tua vita molto più semplice e ti daranno anche il controllo su ciò che è e non è vettorizzato. Al contrario di solo "dare suggerimenti" al compilatore su ciò che dovrebbe essere auto-vettorializzato. – NoseKnowsAll