我正在優化一段移動重力場周圍的粒子的代碼。爲此我們被告知使用SSE。現在,在重寫這一小段代碼之後,我想知道是否有更簡單/更小的方式將值存儲回粒子數組中。SSE將數據複製到變量
下面的代碼之前:
for (unsigned int i = 0; i < PARTICLES; i++) {
m_Particle[i]->x += m_Particle[i]->vx;
m_Particle[i]->y += m_Particle[i]->vy;
}
而這裏的後代碼:
for (unsigned int i = 0; i < PARTICLES; i += 4) {
// Particle position/velocity x & y
__m128 ppx4 = _mm_set_ps(m_Particle[i]->x, m_Particle[i+1]->x,
m_Particle[i+2]->x, m_Particle[i+3]->x);
__m128 ppy4 = _mm_set_ps(m_Particle[i]->y, m_Particle[i+1]->y,
m_Particle[i+2]->y, m_Particle[i+3]->y);
__m128 pvx4 = _mm_set_ps(m_Particle[i]->vx, m_Particle[i+1]->vx,
m_Particle[i+2]->vx, m_Particle[i+3]->vx);
__m128 pvy4 = _mm_set_ps(m_Particle[i]->vy, m_Particle[i+1]->vy,
m_Particle[i+2]->vy, m_Particle[i+3]->vy);
union { float newx[4]; __m128 pnx4; };
union { float newy[4]; __m128 pny4; };
pnx4 = _mm_add_ps(ppx4, pvx4);
pny4 = _mm_add_ps(ppy4, pvy4);
m_Particle[i+0]->x = newx[3]; // Particle i + 0
m_Particle[i+0]->y = newy[3];
m_Particle[i+1]->x = newx[2]; // Particle i + 1
m_Particle[i+1]->y = newy[2];
m_Particle[i+2]->x = newx[1]; // Particle i + 2
m_Particle[i+2]->y = newy[1];
m_Particle[i+3]->x = newx[0]; // Particle i + 3
m_Particle[i+3]->y = newy[0];
}
它的工作原理,但它看起來是增加值到另一個值一樣簡單的方式過大。在不改變m_Particle
結構的情況下是否有更簡單的方法?
這是一種非常常見的情況,優化代碼(尤其是使用SIMD)會導致源代碼變得更大,更復雜。這看起來可能是「錯誤的」和違反直覺的,但只有當你試圖獲得最大的性能時,它纔是你必須接受的。 –