2011-08-10 236 views
2

在在網絡上一個最教程或代碼片段見下表:SSE數據類型和原始類型

float *arr= (float*) _aligned_malloc(length * sizeof(float), 16); 
__m128 *m1 = (__m128*)arr; 

這是否違反嚴格別名規則或不?我會認爲它的確如此,但那麼肯定所有這些教程編寫者都不會忽略它,只是爲了方便起見,因爲__m128是一個包含float的聯合[4],也許我誤解了它的一些複雜部分。

+0

我認爲它確實違反了嚴格的別名規則,除非VC++有特殊情況。希望有人比我可以證實的更專家。另外,您是否比較了使用'_mm_store_ps'和簡單賦值生成的代碼?用這個簡單的代碼,看起來很奇怪,會有任何性能差異。 –

+0

@Cory Nelson對不起,我在編輯之前閱讀它。我測試了幾次(也以不同的順序),並得到了上述結果。重新啓動VS後(沒有改變任何東西!)行爲完全改變了,所以我認爲還有其他事情正在發生,因爲它會很奇怪。此外,由於它似乎違反了嚴格的鋸齒規則,所以我並不在乎 - 我可以任意快速地製作錯誤的代碼;) – Voo

+0

我不確定是否可以回答此問題。如果這是標準的C++,那麼是的,它會違反嚴格的別名規則。但是__m128 __是一個非標準擴展,所以誰來說明規則是什麼。我無法在vC++文檔中找到任何東西,所以我覺得這些規則是你應該作爲C++的擴展所規定的......但是在沒有任何官方聲明的情況下,誰能說?我會安全地使用它,並假設上面的代碼可能有風險 – jcoder

回答

2

這還沒有違反它 - 但。但是,通過一個指針寫入並通過另一個指針讀取會違反嚴格的別名。

相反,你應該使用功能,如:

+0

我認爲,只要我們有兩個指向同一個內存地址的指針,那麼嚴格的別名就已經被違反了,但是顯然我們會從那些地址寫入和讀取指針,所以它沒關係。我使用的是加載和存儲功能,但是我只是被幾乎所有其他人忽略了這個問題而迷惑了(它確實使得代碼更簡短更清晰,所以如果我願意的話會更好)) – Voo

+0

@Voo:不,創建另一個指向同一個對象的指針不違反任何規則,實際上往返指針是允許的。 [這是完整的規則](http://stackoverflow.com/posts/7005988/edit) –

+0

你是對的,沒有太多注意這個細節,因爲一個永遠不會被解除引用的指針將是死代碼,但仍然。 – Voo

1

這是GCC

xmmintrin header for GCC 4.4.3編譯器具體的答案定義如下:

typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));

所以,是的,你違反了嚴格的別名,但你可以這樣做。奇怪的是,__v4sf類型沒有標記爲__may_alias__,所以它不能以這種方式使用。