I try to use 'prange' to accelerate for loop. But it's not useful. There is almost no change in the comparison time. And I also tried 'pool.map' to accelerate the loop. It also has little effect. I give two formats of cython code, which are used for prange and pool.map respectively. Can you give me some advices?
#This is my cython code
cimport cython
import cython
import numpy as np
cimport numpy as np
from cython.parallel import prange,parallel
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
@cython.nonecheck(False)
cdef np.ndarray[np.float32_t,ndim=3] _conv2d_k(np.ndarray[np.float32_t,ndim=4] input,np.ndarray[np.float32_t,ndim=4] filter):
cdef np.ndarray[np.float32_t,ndim=3] output = np.zeros((3,17,17),dtype=np.float32)
cdef unsigned int i,j,di,dj,cl,k
cdef np.float32_t t=0
for k in prange(3,nogil=True):
for di in range(0,6):
for dj in range(0,6):
for i in range(0,17):
for j in range(0,17):
for cl in range(0,256):
output[k,i,j]+=input[k,i + di, j + dj, cl]*filter[k,di, dj, cl]
output = 0.001 * output - 4.184
return output
def conv2d_k(a,b):
return _conv2d_k(a,b)
#for pool.map()
cimport cython
import cython
import numpy as np
cimport numpy as np
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
@cython.nonecheck(False)
cdef np.ndarray[np.float32_t,ndim=2] _conv2d_i(np.ndarray[np.float32_t,ndim=3] input,np.ndarray[np.float32_t,ndim=3] filter):
cdef np.ndarray[np.float32_t,ndim=2] output = np.zeros((17,17),dtype=np.float32)
cdef unsigned int i,j,di,dj,cl
cdef np.float32_t t=0
for di in range(0,6):
for dj in range(0,6):
for i in range(0,17):
for j in range(0,17):
for cl in range(0,256):
output[i,j]+=input[i + di, j + dj, cl]*filter[di, dj, cl]
output = 0.001 * output - 4.184
return output
def conv2d_i(a,b):
return _conv2d_i(a,b)
# my python code
import numpy as np
import time
import threading
import multiprocessing
import conv2d_k
import conv2d_i
from multiprocessing import Pool
from multiprocessing.dummy import Pool as ThreadPool
def job(z):
return conv2d_i.conv2d_i(z[0], z[1])
def main():
input=np.random.rand(3,22, 22,256).astype(np.float32)
kernel=np.random.rand(3,6,6,256).astype(np.float32)
start1 = time.time()
for i in range(3):
conv2d_i.conv2d_i(input[i], kernel[i])
end1=time.time()
print(end1-start1)
# ----------------------------
pool = ThreadPool(3)
data=[(input[0],kernel[0]),(input[1],kernel[1]),(input[2],kernel[2])]
start2 = time.time()
pool.map(job,data)
end2 = time.time()
print(end2 - start2)
# ----------------------------
start3=time.time()
output2=conv2d_k.conv2d_k(input,kernel)
end3=time.time()
print(end3-start3)
if __name__ == '__main__':
main()
for loop time:0.012341022491455078
pool.map() time:0.013735532760620117
prange time:0.013698816299438477