2010-12-12 54 views
12

按值對齊類型或結構傳遞對齊類型不適用於某些實現。這打破了STL容器,因爲一些方法(如調整大小)通過價值取得它們的參數。按值排列類型並傳遞參數

我用Visual Studio 2008運行一些測試,並不完全確定何時以及如何通過值傳遞失敗。我主要關心的是功能foo。它似乎工作正常,但可能是內聯或其他巧合的結果?如果我將其簽名更改爲void foo(const __m128 &)

非常感謝您的輸入。謝謝。

struct A 
{ 
    __m128 x; 
    int n; 
}; 

void foo(__m128); 
void bar(A); 

void f1() 
{ 
    // won't compile 
    // std::vector<A> vec1(3); 

    // compiles, but fails at runtime when elements are accessed 
    std::vector<__m128> vec2(3); 

    // this seems to work. WHY??? 
    std::vector<__m128, some_16_byte_aligned_allocator<__m128> > vec3(3); 

    __m128 x; 
    A a; 

    // passed by value, is it OK? 
    foo(x); 

    // won't compile 
    //bar(a); 
} 

編輯。即使使用對齊的分配器,STL也會失敗,因爲值傳遞問題依然存在。

發現這個鏈接pass __m128 by value

+0

你得到的編譯錯誤/警告是什麼?我假設像「正式參數...不會對齊」? – celion 2010-12-13 00:31:37

+0

這就是我得到的。錯誤C2719:'unnamed-parameter':具有__declspec(align('16'))的形式參數將不會對齊 – watson1180 2010-12-13 00:43:12

+0

在x64中,函數參數支持16字節對齊,所以此問題消失。我知道這並不能解決你眼前的問題,但嘿,這比稍微好一點。 ;) – jalf 2010-12-13 05:44:05

回答

2

我認爲唯一安全的方法一般要做到這一點是通過引用傳遞。某些平臺(例如Xbox 360)支持在寄存器中傳遞向量參數,但我認爲這在x86上不可行。

對於std::vector的情況,您需要確保分配的內存對齊到16個字節;否則當您嘗試對未對齊的向量執行大部分操作時會發生崩潰。

如果您支持多個平臺,則安全計劃是使用例如typedef

typedef const MyVector& MyVectorParameter; 

然後,您可以在支持向量傳遞的平臺上更改typedef。

+0

用std :: vector <__m128>替換分​​配器幫助,但std :: vector 仍然不能編譯。 – watson1180 2010-12-13 00:56:05

+0

您是否檢查過sizeof(A)'?如果它不是16字節的倍數,那麼即使存儲的開始對齊,由矢量分配的數組存儲的後續元素也不會對齊。 – 2010-12-13 01:21:06

+0

在我的平臺上,A的大小是32個字節。錯誤的對齊會導致運行時崩潰,但矢量將不會編譯,無論分配器。 – watson1180 2010-12-13 03:12:32

1

經常使用的resize()函數會導致所有對齊,也許您可​​以嘗試專門化__m128的矢量模板?