2014-04-14 132 views
1

我不明白,爲什麼評論和註釋掉線不產生相同的結果(GCC的Linux與C++ 11標誌啓用):C++:英特爾SIMD內在類成員的初始化

#include "immintrin.h" 


typedef __m256 floatv; 

struct floatv2{ 
public: 

    //floatv2(const float f):x(_mm256_setzero_ps() + f), y(_mm256_setzero_ps() + f) {}; // succeeds 
    floatv2(const float f):x{_mm256_setzero_ps() + f }, y{_mm256_setzero_ps() + f } {}; // fails 

//private: 
    floatv x, y; 
}; 

當試圖編譯註釋掉線我得到以下錯誤:

error: cannot convert ‘__m256 {aka __vector(8) float}’ to ‘float’ in initialization 

我不理解,因爲xy是floatv,不浮動,所以沒有轉換應要求...

另外,在一些更復雜的代碼中,第一個版本會產生內存訪問衝突。幕後有什麼不愉快的事情發生嗎?

PS:的__m256上面的定義,在avxintrin.h,有以下評論:

/* The Intel API is flexible enough that we must allow aliasing with other 
    vector types, and their scalar components. */ 

我不明白這是什麼意思,但覺得它可能與:)

非常感謝

+0

錯誤,請報告給gcc的bugzilla。 –

+1

看起來像一個Bug。順便說一下,因爲你已經在使用_mm256_setzero_ps(),所以沒有理由添加f,只需使用'_mm256_set1_ps()'或'_mm256_broadcast_ps()'直接使用廣播。這樣做的唯一理由是你不必使用內在的東西。定義'__m256零= {}'做'零+ f' http://stackoverflow.com/questions/21727331/implict-simd-sse-avx-broadcasts-with-gcc –

+0

好點;我一定會用_mm256_set1_ps(f)代替。但是,這個問題仍然在使用_mm256_set1_ps。將向GCC bugzilla報告。非常感謝球員 – GHL

回答

2

這與DR 1467有關,它不允許使用列表初始化語法來複制聚集。這是最近修復的海灣合作委員會的類,我擴大修復向量在r209449。 Gcc-4.10編譯你的代碼。

+0

Great Marc,非常感謝! – GHL

0

可能_mm256_setzero_ps()+ f返回一個浮點數而不是一個floatv,因爲f是一個浮點數。 因此,您無法使用{}使用float初始化floatv值(x和y),因此{} - 初始化不允許縮小(隱式轉換)。

也許

x{static_cast<__m256>(_mm256_setzero_ps() + f) } 

會工作。

+0

嗨,這很不幸失敗了,x {_mm256_set1_ps(f)}和x {static_cast <__m256>(_mm256_set1_ps(f))}也失敗了...... – GHL