首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多核程序设计

多核程序设计
EN

Stack Overflow用户
提问于 2020-05-25 14:42:30
回答 2查看 245关注 0票数 0

在我实习的公司,我被告知多核编程的使用,并且,鉴于我正在为我的论文开发一个项目(我不是来自这个领域,但我正在做一些涉及编码的事情)。

我想知道这是否可能:

我有一个定义的函数,对于3个不同的变量,它将被重复3x。是否可以将3同时运行在不同的核心中(因为它们不需要彼此的信息)?因为计算过程对所有这些变量都是相同的,所以我不想一次运行一个变量,而是一次运行所有3个变量(同时执行所有计算),最后返回结果。

我想要优化的部分是:

代码语言:javascript
复制
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实现相同的过程。

是否有可能使它们同时发生呢?

,因为我将使用大量的数据,这可能会为我节省一些处理时间。

EN

回答 2

Stack Overflow用户

发布于 2020-05-25 15:14:34

这是可能的,但是使用python多处理库,因为线程库不提供并行执行。

更新

不需要这样做(感谢@user3666197指出错误):

代码语言:javascript
复制
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

相反,像这样的事情应该能做好:

代码语言:javascript
复制
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内核,否则,您的系统内核只会在进程之间切换,并且不会真正并行运行。

票数 0
EN

Stack Overflow用户

发布于 2020-05-25 16:34:31

multiprocessing (使用进程来避免GIL)是最简单的,但是您仅限于相对较小的性能改进,核加速的数量是限制,参见Amdahl定律。在开始/停止工作时也有一些延迟,这意味着对于花费超过10‘s的事情来说它要好得多

在大量的数值代码(像这样的代码)中,您确实想要移动“numpy”中的大量代码,看看矢量化广播业。这可以使速度超过50倍(仅在单个核上),同时保持更容易理解和解释的情况。

如果您的算法很难用numpy本质表示,那么您也可以考虑使用Cython。这允许您编写自动编译到C的Python代码,因此速度要快得多。50倍的速度可能也是一种合理的加速,而且它仍然运行在单个核上。

numpy和Cython技术可以与multiprocessing (即使用多个核)相结合,从而提供比简单实现快数百倍的代码。

木星笔记本有友好的扩展(亲切地被称为“魔术”),使它更容易开始这种性能工作。%timeit特殊功能允许您轻松地计时代码的各个部分,而Cython扩展意味着您可以将所有内容放入同一个文件中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62004781

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档