2016-11-17 70 views
1

我有以下說明:使用OMP SIMD沒有爲

unsigned long int xDiff = seq1.x^seq2.x; 
unsigned long int yDiff = seq1.y^seq2.y; 
unsigned long int zDiff = seq1.z^seq2.z; 

有可能向量化這種使用omp simd

+0

你的變量是如何聲明的?你真的需要矢量化只有三個操作?他們是在一個循環? –

+0

@VladimirF這是來自cuda_api的ulong3結構(在cuda和XeonPhi中運行的代碼)。是的,它在一段時間內(不能在表單中轉換)。 –

回答

1

實際上,如果您將位置定義爲數組,則不需要執行任何操作,編譯器會爲您進行矢量化。

struct position { 
    unsigned long pos[3]; 
}; 

struct position foo(struct position seq1, struct position seq2) { 
    struct position diff; 

    for(int i = 0; i < 2; ++i) 
    diff.pos[i] = seq1.pos[i]^seq2.pos[i]; 

    return diff; 
} 

GCC 4.6,因爲將利用剛剛-O3標誌矢量化它。如果您提供體系結構特定標誌(例如,使用英特爾向量擴展:-msse42,-mavx等),則可以控制編譯器必須使用哪個向量指令集。如果你只想爲你自己的機器構建,你可以編譯爲-march=native

foo(position, position): 
    movdqu xmm1, XMMWORD PTR [rsp+32] 
    mov  rax, rdi 
    movdqu xmm0, XMMWORD PTR [rsp+8] 
    pxor xmm0, xmm1 
    movdqu XMMWORD PTR [rdi], xmm0 
    ret 

如果你(在你的例子一樣) 「手動展開循環」

diff.pos[0] = seq1.pos[0]^seq2.pos[0]; 
diff.pos[1] = seq1.pos[1]^seq2.pos[1]; 
diff.pos[2] = seq1.pos[2]^seq2.pos[2]; 

這不再是這種情況:

foo(position, position): 
    mov  rdx, QWORD PTR [rsp+32] 
    xor  rdx, QWORD PTR [rsp+8] 
    mov  rax, rdi 
    mov  QWORD PTR [rdi], rdx 
    mov  rdx, QWORD PTR [rsp+40] 
    xor  rdx, QWORD PTR [rsp+16] 
    mov  QWORD PTR [rdi+8], rdx 
    mov  rdx, QWORD PTR [rsp+48] 
    xor  rdx, QWORD PTR [rsp+24] 
    mov  QWORD PTR [rdi+16], rdx 
    ret 

此外,#pragma omp simd指令只能是適用於循環:

simd [2.8.1]應用於一個循環指示循環可以轉換爲SIMD循環。

#pragma omp simd [clause[,] clause] ...] 
    for-loops