2017-08-28 50 views
0

我已經litterally花費周(在用Cython仍然雖然)改變我用Cython代碼以純C獲得速度併成爲能夠刪除GIL以執行多線程以獲得更高的速度。用Cython numpy的ndarray(N,4,2)轉換爲矢量[向量[對[雙,雙]]

與其他計算器的用戶的幫助下,我終於通過使用4個線程(與PRANGE)的雙重成功,並獲得了10倍純C VS用Cython一些蟒蛇,然後再一個因素3的循環部分我碼。

BUT爲了進入該循環我首先必須兩個維度(N,4,2)的3維numpy ndarrays(和(K,4,2))轉換爲vector[vector[pair[double,double]]]。 K和N相當大。

對於這個我做的:

cdef int N=200000 #Of this order of magnitude 
cdef np.ndarray[DTYPE_t,ndim=3] numpy_array=np.random.uniform(size=(N,4,2)) 
t1=time.time() 
cdef vector[vector[pair[double,double]]] c_structure 
c_structure.reserve(N) 
cdef int i 
for i in range(N): 
    c_structure.push_back(numpy_array[i]) 
t2=time.time() 

然而,這部分代碼,我認爲瑣碎已經成爲我的代碼的新的瓶頸! for循環的雙重需要我的電腦0.1S(而不是在原來的實現1.11s)單個線程上,這部分需要3整秒(1.5s的每個陣列)!這使得我的超級優化代碼比我原來的代碼慢了3倍(1.5 * 2 + 0.1)!

我在做什麼錯?!如何加速這個?!

another related question that I asked

+1

在這方面並不重要,但'np.random.uniform((N,4,2))'不返回3D陣列...請儘量讓[mcve]至少相對正確。 – MSeifert

+0

感謝它現在糾正了 – jean

+0

大部分時間是否有可能產生隨機數? –

回答

0

我在速度通過明確地初始化向量的每個元素贏得了100倍。事實上,一個cython-a現在有0條黃線。

cdef int N=200000 #Of this order of magnitude 
cdef np.ndarray[DTYPE_t,ndim=3] numpy_array=np.random.uniform(size=(N,4,2)) 
t1=time.time() 
cdef vector[vector[pair[double,double]]] c_structure 
cdef vector[pair[double,double]] empty_vector, vector 
cdef pair[double,double] a1, a2, a3, a4 
c_structure.reserve(N) 
cdef int i 
for i in range(N): 
    a1.first=numpy_array[i,0,0] 
    a1.second=numpy_array[i,0,1] 
    a2.first=numpy_array[i,1,0] 
    a2.second=numpy_array[i,1,1] 
    a3.first=numpy_array[i,2,0] 
    a3.second=numpy_array[i,2,1] 
    a4.first=numpy_array[i,3,0] 
    a4.second=numpy_array[i,3,1] 
    vector.push_back(a1) 
    vector.push_back(a2) 
    vector.push_back(a3) 
    vector.push_back(a4) 
    c_structure.push_back(vector) 
    vector=empty_vector 
t2=time.time() 

0.036s,而不是3S

+0

很高興看到你在正確的軌道上。如果你只是在頂部添加一個'vector.resize(4)',然後直接賦值給它,'empty_vector'和a1/a2/a3/a4就可以被刪除。 'vector [0] .first = numpy_array [i,0,0]'。 –

+0

感謝您的評論!我不知道.resize()方法! – jean

2

你有一個Nx4x2陣列且將其轉換爲vector[vector[pair[double,double]]。在C++中,向量的向量效率不高。相反,你應該創建一個4x2結構並且創建這些結構的一個向量。或者,更好的是,您應該直接使用C++中的NumPy數組作爲指向Nx4x2數組的指針。換句話說,停止不必要地複製數據,但是如果有必要,請將其複製到固定的Nx4x2結構中,而不是緩慢的NxMx2。

+0

我提高了答案,但是我發現了一個更好的方法,並在初始化時贏得了一個因子100。 – jean

+0

我很可能會考慮結構後 – jean

+0

我有我的原因有載體內大小可變的結構,所以我需要有一個'fixed_size_vector [variable_sized_vector [(雙,雙)]'這就是爲什麼我選擇了'向量向量雙[雙,雙]]]' – jean