3

+ AVX を使用して Python コードの一部を最適化しようとしています。ctypes を使用して C++ 関数にアクセスしています。関数が segfault することもあれば、そうでないこともあります。ひょっとしてアライメントと関係あるのかな?多分誰かがこれで私を助けることができます、私はちょっとここで立ち往生しています。

Python コード:

from ctypes import *
import numpy as np
#path_cnt
path_cnt = 16
c_path_cnt = c_int(path_cnt)

#ndarray1
ndarray1      = np.ones(path_cnt,dtype=np.float32,order='C')
ndarray1.setflags(align=1,write=1)
c_ndarray1     = stock.ctypes.data_as(POINTER(c_float))

#ndarray2
ndarray2    = np.ones(path_cnt,dtype=np.float32,order='C');
ndarray2.setflags(align=1,write=1)
c_ndarray2  = max_vola.ctypes.data_as(POINTER(c_float))

#call function
finance = cdll.LoadLibrary(".../libfin.so")
finance.foobar.argtypes = [c_void_p, c_void_p,c_int]
finance.foobar(c_ndarray1,c_ndarray2,c_path_cnt)
x=0
while x < path_cnt:   
    print  c_stock[x]
    x+=1

C++ コード

extern "C"{
int foobar(float * ndarray1,float * ndarray2,int path_cnt)
 {
     for(int i=0;i<path_cnt;i=i+8)
     {
         __m256 arr1                = _mm256_load_ps(&ndarray1[i]);
         __m256 arr2                    = _mm256_load_ps(&ndarray2[i]);
         __m256 add                 = _mm256_add_ps(arr1,arr2);
         _mm256_store_ps(&ndarray1[i],add);
     }
     return 0;
 }
}

そして今、奇妙な出力動作、ターミナルでいくつかの呼び出しを2回行うと、異なる結果が得られます!

tobias@tobias-Lenovo-U310:~/workspace/finance$ python finance.py 
Segmentation fault (core dumped)
tobias@tobias-Lenovo-U310:~/workspace/finance$ python finance.py 
2.0
2.0
2.0
2.0
2.0
2.0
2.0
2.0

前もって感謝します!

4

2 に答える 2

6

アライメントされたロード命令とアライメントされていないロード命令があります。整列ルールに違反すると、整列されたものは失敗しますが、より高速です。アライメントされていないものは、任意のアドレスを受け入れ、内部でロード/シフトを実行して、必要なデータを取得します。アライメントされたバージョンを使用しており、中間の割り当てなし_mm256_load_psでアライメントされていないバージョンに切り替えることができます。_mm256_loadu_ps

優れたベクトル化コンパイラには、アラインされたアドレスに到達するためのリードイン ループ、アラインされたデータを操作するための本体、ストラグラーをクリーンアップするための最終ループが含まれます。

于 2013-09-14T19:40:14.647 に答える
1

よし、私はsultionを見つけた気がする、それはあまりエレガントではないが、少なくとも動作する! より良い方法であるべきです、誰か何か提案はありますか?

extern "C"{
int foobar(float * ndarray1,float * ndarray2,int path_cnt)
 {
     float * test = (float*)_mm_malloc(path_cnt*sizeof(float),32);
     float * test2 = (float*)_mm_malloc(path_cnt*sizeof(float),32);
     //copy to aligned memory(this part is kinda stupid)
     for(int i=0;i<path_cnt;i++)
     {
        test[i] = stock[i];
        test2[i] = max_vola[i];

     }
     for(int i=0;i<path_cnt;i=i+8)
     {
         __m256 arr1                = _mm256_load_ps(&test1[i]);
         __m256 arr2                    = _mm256_load_ps(&test2[i]);
         __m256 add                 = _mm256_add_ps(arr1,arr2);
         _mm256_store_ps(&test1[i],add);
     }
  //and copy everything back!
   for(int i=0;i<path_cnt;i++)
    {
    stock[i] = test[i];   
    }
     return 0;
 }
}
于 2013-09-14T19:10:24.270 に答える