2017-02-27 239 views
0

我在C++下面的代碼:寫彙編代碼的C++

inline void armMultiply(const float* __restrict__ src1, 
         const float* __restrict__ src2, 
         float* __restrict__ dst) 
{ 
    __asm volatile(
       "vld1.f32 {q0}, [%[src1]:128]!  \n\t" 
       : 
       :[dst] "r" (dst), [src1] "r" (src1), [src2] "r" (src2) 
       ); 
} 

爲什麼我得到錯誤向量寄存器預期?

+5

除了使用內聯彙編,還應該考慮使用內在函數,比如''•float32x2_t vld1_f32(const float32_t *) ''。內聯彙編對C++編譯器的優化能力造成嚴重限制。 –

+0

是的,但我想加載2個數組的4個浮點,每個到q1和q2寄存器,然後乘,我無法控制加載的q1,2在c,這會導致額外的負載從內存當我打電話給vld1q兩次 – shd

回答

1

你得到這個錯誤,因爲你的內聯彙編的32位ARM,但你正在編譯爲64位ARM(鏗鏘 - 用gcc你會得到一個不同的錯誤)。

(內聯)組件在32位和64位手臂之間是不同的,因此您需要使用#if defined(__ARM_NEON__) && !defined(__aarch64__),或者如果你想有不同的裝配兩個64位和32位:#ifdef __aarch64__ .. #elif defined(__ARM_NEON__)

正如其他人評論說,除非你真的需要手動handtune的生產裝配,內聯函數可以一樣好(在某些情況下,比你自己生產的更好)。你可以例如通過內在函數完成兩個vld1_f32調用,一個vmul_f32和一個vst1_f32就好了。

編輯:

相應的內聯彙編線加載到64位SIMD寄存器是:

"ld1 {v0.4s}, [%[src1]], #16  \n\t" 

要支持,你的函數看起來是這樣,而不是:

inline void armMultiply(const float* __restrict__ src1, 
         const float* __restrict__ src2, 
         float* __restrict__ dst) 
{ 
#ifdef __aarch64__ 
    __asm volatile(
       "ld1 {v0.4s}, [%[src1]], #16  \n\t" 
       : 
       :[dst] "r" (dst), [src1] "r" (src1), [src2] "r" (src2) 
       ); 
#elif defined(__ARM_NEON__) 
    __asm volatile(
       "vld1.f32 {q0}, [%[src1]:128]!  \n\t" 
       : 
       :[dst] "r" (dst), [src1] "r" (src1), [src2] "r" (src2) 
       ); 
#else 
#error this requires neon 
#endif 
} 
+0

我怎樣才能使它裝配爲64位? – shd

0

假設我們正在討論GCC,文檔說您應該使用「w」(「浮點或SIMD向量寄存器」)而不是「r」(「只要寄存器操作數在通用註冊「)作爲約束條件。

https://gcc.gnu.org/onlinedocs/gcc-6.3.0/gcc/Machine-Constraints.html#Machine-Constraints

https://gcc.gnu.org/onlinedocs/gcc-6.3.0/gcc/Simple-Constraints.html#Simple-Constraints

+0

如果您引用的是實際上包含浮點向量的寄存器,則會是這種情況,但在這種情況下,dst/src1/src2變量是保留在常規通用寄存器中的普通指針變量。 – mstorsjo