在我实习的公司,我被告知多核编程的使用,并且,鉴于我正在为我的论文开发一个项目(我不是来自这个领域,但我正在做一些涉及编码的事情)。
我想知道这是否可能:
我有一个定义的函数,对于3个不同的变量,它将被重复3x。是否可以将3同时运行在不同的核心中(因为它们不需要彼此的信息)?因为计算过程对所有这些变量都是相同的,所以我不想一次运行一个变量,而是一次运行所有3个变量(同时执行所有计算),最后返回结果。
我想要优化的部分是:
for v in [obj2_v1, obj2_v2, obj2_v3]:
distancia_final_v, \
pontos_intersecao_final_v = calculo_vertice( obj1_normal,
obj1_v1,
obj1_v2,
obj1_v3,
obj2_normal,
v,
criterio
)
def calculo_vertice( obj1_normal,
obj1_v1,
obj1_v2,
obj1_v3,
obj2_normal,
obj2_v,
criterio
):
i = 0
distancia_final_v = []
pontos_intersecao_final_v = []
while i < len(obj2_v):
distancia_relevante_v = []
pontos_intersecao_v = []
distancia_inicial = 1000
for x in range(len(obj1_v1)):
planeNormal = np.array( [obj1_normal[x][0],
obj1_normal[x][1],
obj1_normal[x][2]
] )
planePoint = np.array( [ obj1_v1[x][0],
obj1_v1[x][1],
obj1_v1[x][2]
] ) # Any point on the plane
rayDirection = np.array([obj2_normal[i][0],
obj2_normal[i][1],
obj2_normal[i][2]
] ) # Define a ray
rayPoint = np.array([ obj2_v[i][0],
obj2_v[i][1],
obj2_v[i][2]
] ) # Any point along the ray
Psi = Calculos.line_plane_collision( planeNormal,
planePoint,
rayDirection,
rayPoint
)
a = Calculos.area_trianglo_3d( obj1_v1[x][0],
obj1_v1[x][1],
obj1_v1[x][2],
obj1_v2[x][0],
obj1_v2[x][1],
obj1_v2[x][2],
obj1_v3[x][0],
obj1_v3[x][1],
obj1_v3[x][2]
)
b = Calculos.area_trianglo_3d( obj1_v1[x][0],
obj1_v1[x][1],
obj1_v1[x][2],
obj1_v2[x][0],
obj1_v2[x][1],
obj1_v2[x][2],
Psi[0][0],
Psi[0][1],
Psi[0][2]
)
c = Calculos.area_trianglo_3d( obj1_v1[x][0],
obj1_v1[x][1],
obj1_v1[x][2],
obj1_v3[x][0],
obj1_v3[x][1],
obj1_v3[x][2],
Psi[0][0],
Psi[0][1],
Psi[0][2]
)
d = Calculos.area_trianglo_3d( obj1_v2[x][0],
obj1_v2[x][1],
obj1_v2[x][2],
obj1_v3[x][0],
obj1_v3[x][1],
obj1_v3[x][2],
Psi[0][0],
Psi[0][1],
Psi[0][2]
)
if float("{:.5f}".format(a)) == float("{:.5f}".format(b + c + d)):
P1 = Ponto( Psi[0][0], Psi[0][1], Psi[0][2] )
P2 = Ponto( obj2_v[i][0], obj2_v[i][1], obj2_v[i][2] )
distancia = Calculos.distancia_pontos( P1, P2 ) * 10
if distancia < distancia_inicial and distancia < criterio:
distancia_inicial = distancia
distancia_relevante_v = []
distancia_relevante_v.append( distancia_inicial )
pontos_intersecao_v = []
pontos_intersecao_v.append( Psi )
x += 1
distancia_final_v.append( distancia_relevante_v )
pontos_intersecao_final_v.append( pontos_intersecao_v )
i += 1
return distancia_final_v, pontos_intersecao_final_v在这个代码示例中,我希望为obj2_v1, obj2_v2, obj2_v3实现相同的过程。
是否有可能使它们同时发生呢?
,因为我将使用大量的数据,这可能会为我节省一些处理时间。
发布于 2020-05-25 15:14:34
这是可能的,但是使用python多处理库,因为线程库不提供并行执行。
更新
不需要这样做(感谢@user3666197指出错误):
from multiprocessing.pool import ThreadPool
def calculo_vertice(obj1_normal,obj1_v1,obj1_v2,obj1_v3,obj2_normal,obj2_v,criterio):
#your code
return distancia_final_v,pontos_intersecao_final_v
pool = ThreadPool(processes=3)
async_result1 = pool.apply_async(calculo_vertice, (#your args here))
async_result2 = pool.apply_async(calculo_vertice, (#your args here))
async_result3 = pool.apply_async(calculo_vertice, (#your args here))
result1 = async_result1.get() # result1
result2 = async_result2.get() # result2
result3 = async_result3.get() # result3相反,像这样的事情应该能做好:
from multiprocessing import Process, Pipe
def calculo_vertice(obj1_normal,obj1_v1,obj1_v2,obj1_v3,obj2_normal,obj2_v,criterio, send_end):
#your code
send_end.send((distancia_final_v,pontos_intersecao_final_v))
numberOfWorkers = 3
jobs = []
pipeList = []
#Start process and build job list
for i in range(numberOfWorkers):
recv_end, send_end = Pipe(False)
process = Process(target=calculo_vertice, args=(#<... your args...>#, send_end))
jobs.append(process)
pipeList.append(recv_end)
process.start()
#Show the results
for job in jobs: job.join()
resultList = [x.recv() for x in pipeList]
print (resultList)参考
https://docs.python.org/3/library/multiprocessing.html https://stackoverflow.com/a/37737985/8738174
此代码将创建一个由3个工作流程组成的池,每个流程都将接收该函数。重要的是要指出,在这种情况下,您应该拥有3+ CPU内核,否则,您的系统内核只会在进程之间切换,并且不会真正并行运行。
发布于 2020-05-25 16:34:31
multiprocessing (使用进程来避免GIL)是最简单的,但是您仅限于相对较小的性能改进,核加速的数量是限制,参见Amdahl定律。在开始/停止工作时也有一些延迟,这意味着对于花费超过10‘s的事情来说它要好得多
在大量的数值代码(像这样的代码)中,您确实想要移动“numpy”中的大量代码,看看矢量化和广播业。这可以使速度超过50倍(仅在单个核上),同时保持更容易理解和解释的情况。
如果您的算法很难用numpy本质表示,那么您也可以考虑使用Cython。这允许您编写自动编译到C的Python代码,因此速度要快得多。50倍的速度可能也是一种合理的加速,而且它仍然运行在单个核上。
numpy和Cython技术可以与multiprocessing (即使用多个核)相结合,从而提供比简单实现快数百倍的代码。
木星笔记本有友好的扩展(亲切地被称为“魔术”),使它更容易开始这种性能工作。%timeit特殊功能允许您轻松地计时代码的各个部分,而Cython扩展意味着您可以将所有内容放入同一个文件中。
https://stackoverflow.com/questions/62004781
复制相似问题