2012-09-12 58 views
3

我一直在試圖重新實現一些現有的向量和矩陣類來使用SSE3命令,而且我似乎遇到這些「內存訪問衝突」錯誤,只要我執行一系列對一組向量的操作。我對SSE比較陌生,所以我從簡單開始。這是我的矢量類的全部:使用SSE操作時的內存訪問衝突

class SSEVector3D 
{ 
public: 

    SSEVector3D(); 
    SSEVector3D(float x, float y, float z); 

    SSEVector3D& operator+=(const SSEVector3D& rhs); //< Elementwise Addition 

    float x() const; 
    float y() const; 
    float z() const; 

private: 

    float m_coords[3] __attribute__ ((aligned (16))); //< The x, y and z coordinates 

}; 

所以,不是一大堆事情還沒有,只是一些構造函數,訪問器和一個操作。使用SSE我的(當然有限)的知識,我實現了加法運算如下:

SSEVector3D& SSEVector3D::operator+=(const SSEVector3D& rhs) 
{ 
    __m128 * pLhs = (__m128 *) m_coords; 
    __m128 * pRhs = (__m128 *) rhs.m_coords; 

    *pLhs = _mm_add_ps(*pLhs, *pRhs); 

    return (*this); 
} 

爲了加速測試我新的向量類不服老的(看看它是否值得重新實現了整個事情) ,我創建了一個簡單的程序,生成一個隨機的SSEVector3D對象數組並將它們添加到一起。沒有太複雜:

SSEVector3D sseSum(0, 0, 0); 

for(i=0; i<sseVectors.size(); i++) 
{ 
    sseSum += sseVectors[i]; 
} 

printf("Total: %f %f %f\n", sseSum.x(), sseSum.y(), sseSum.z()); 

sseVectors變量是含有SSEVector3D類型,所使用的組件和-1之間1所有初始化爲隨機數的元素的的std ::向量。

這是我遇到的問題。如果sseVectors的尺寸是8,191或更少(我通過大量的試驗和錯誤得出的數字),這運行良好。

信號:SIGSEGV,si_code:如果大小爲8,192以上,我當我嘗試運行它得到這個錯誤0(地址內存訪問衝突:0x00000080)

但是,如果我在最後打印出的聲明發表了意見,即使sseVectors的尺寸爲8,192或更多,我也沒有錯誤。

我寫這個向量類的方式有什麼問題嗎?我運行Ubuntu 12.04.1與GCC 4.6版

+5

請參見:[矢量的數據如何對齊?](http://stackoverflow.com/questions/8456236/how-is-a-vectors-data (對等)(另外,對於寫得很好的第一個問題,+1。) – Mysticial

+1

由於STL容器不符合SSE,因此您正在收到段錯誤。 '8192'發生的奇怪現象只是內存分配器中影響返回指針對齊的工件。 – Mysticial

+1

我認爲需要考慮的一個重要問題是'_mm_add_ps()'例程中加載了多少數據,並且可能更關鍵的是寫回了多少數據。這與你的浮點數組的實際大小有什麼關係?我想這個答案會指出至少三個問題 - 錯誤的計算結果,對齊問題和數組溢出... – twalberg

回答

1

首先,也是最重要的,不這樣做

__m128 * pLhs = (__m128 *) m_coords; 
__m128 * pRhs = (__m128 *) rhs.m_coords; 
*pLhs = _mm_add_ps(*pLhs, *pRhs); 

隨着SSE,總是做你的加載和存儲明確地通過適當的內部函數, 從來沒有只是解除引用。而不是在您的班級中存儲3個浮點數組,請存儲類型爲_m128的值。這應該會使編譯器正確地對齊類的實例,而不需要任何align屬性。

但是,請注意,這將無法與MSVC很好地工作。 MSVC似乎通常無法應付強於8字節對齊值的對齊要求: - (。上次我需要將SSE代碼移植到窗口時,我的解決方案是使用Intel的C++編譯器來處理SSE部分而不是MSVC ...

0

關鍵是要注意__m128是對齊的16字節,使用_malloc_aligned(),以確保您的float數組正確對齊,那麼你就可以繼續投你浮到的__m128數組。讓當然,你分配的浮點數可以被4整除。