我寫了一個使用大量SSE編譯器內在函數的3D矢量類。一切正常,直到我開始安裝具有3D矢量作爲新成員的類。我在發佈模式下遇到了奇怪的崩潰,但不是在調試模式下,反之亦然。SSE,內在函數和對齊
因此,我讀了一些文章,並認爲我需要將擁有3D矢量類的實例的類也對齊到16字節。於是我就在班級前面加_MM_ALIGN16
(__declspec(align(16)
)像這樣:
_MM_ALIGN16 struct Sphere
{
// ....
Vector3 point;
float radius
};
這似乎在首先要解決的問題。但更改一些代碼後,我的程序又開始以奇怪的方式崩潰。我在網上搜索了一些,發現了一篇blog文章。我嘗試了作者Ernst Hot爲解決問題所做的工作,它對我也很有用。我加了new和delete操作符來我的班是這樣的:
_MM_ALIGN16 struct Sphere
{
// ....
void *operator new (unsigned int size)
{ return _mm_malloc(size, 16); }
void operator delete (void *p)
{ _mm_free(p); }
Vector3 point;
float radius
};
恩斯特提到,這個形式給出可能是有問題的爲好,但他只是鏈接到它不沒有解釋爲什麼它可能會有問題存在了一個論壇。
所以我的問題是:
什麼是與定義運營商的問題?
爲什麼不將
_MM_ALIGN16
添加到類定義足夠?處理SSE內在函數的對齊問題的最佳方法是什麼?
在第一種情況下,你是在棧還是堆上分配結構?我不確定malloc會默認返回對齊的內存,而_mm_malloc肯定會 - 「一段時間後我的程序開始再次崩潰」是什麼意思?你的意思是在離開它後運行一段時間(以及它在做什麼)? – Thomas
當我開始在堆上分配結構時,問題就開始了。隨着「一段時間」的句子,我的意思是說,它改變了代碼後開始崩潰。我想這個對齊是正確的,然後我把它摧毀了。我認爲malloc不會返回內存16字節對齊,這是我猜的問題。我的問題實際上是運營商方法的問題是什麼,以及使用SSE內在函數管理代碼的最佳方式是什麼。 –
事實上,你不需要指定'Sphere'的對齊方式(使用這個'_MM_ALIGN16'的東西),因爲編譯器足夠聰明,可以看到'Sphere'有一個16對齊的成員並自動調整'Sphere' s的對齊要求(鑑於'Vector3'已正確對齊)。這就是爲什麼如果它已經有'__m128'成員,你不必明確地對齊Vector3。只有動態分配是一個問題,這可以通過重載'operator new/delete'來克服,就像寫在博客中一樣(通常還有其他的東西,比如專門用於'std :: allocator'的)。 –