MSVC 2013 Ultimative w/Update 4Fehlerbehebung Auto vectorize Grund ‚1200‘
nicht verstehen, warum ich auf diesem scheinbar einfachen Beispiel diesen Fehler bin immer
Info C5002: Schleife nicht auf Grund ‚1200‘ vektorisiert durch
welches
1200 Schleife enthält schlaufen getragenen Daten abhängigkeit
sehe ich nicht, wie die Iterationen der l oop könnte sich gegenseitig stören.
__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: Gemessen an http://blogs.msdn.com/b/nativeconcurrency/archive/2012/05/08/auto-vectorizer-in-visual-studio-11-rules-for-loop-body.aspx Dies scheint ein Beispiel für „Beispiel 1 - Peinlich Parallel“ zu sein, aber es wirkt wie es die Arrays sind unsicher von Aliasing denkt, die mir rätselhaft.
Edit2: Es wäre schön, wenn jemand die Gründe teilen könnte, warum die automatische Vektorisierung auf eine solche scheinbar einfachen Beispiel ausfällt, aber mit ihm für einige Zeit nach bastelt, ich stattdessen entschied mich die Zügel zu nehmen
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));
}
}
Nur 2 Anmerkungen: 1/Da die Update-Methode inline ist, als ich versuchte, dies zu kompilieren, passierte nichts, was mich eine Weile verwirrte; und 2/jetzt, dass ich es nicht-inlined, Intel-Compiler-Version 15.0.3 einfach nur ohne Probleme vektorisiert. – Gilles
Danke. Und interessant. MSVC 2015 mag es auch nicht – jswigart
Ich würde sicherlich vorschlagen, dass Sie in portable Vektorisierung suchen (aka mit OpenMP 4.0-'#pragma omp simd'). Angenommen, Sie haben einen Compiler, der dies unterstützt (icc 15+, glaube ich), dann wird es Ihnen sowohl das Leben erleichtern als auch Ihnen die Kontrolle darüber geben, was vektorisiert ist und was nicht. Im Gegensatz dazu, dem Compiler nur Vorschläge zu machen, was automatisch vektorisiert werden sollte. – NoseKnowsAll