2017-08-28 55 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