如何并行化嵌套的for循环,以使其真正更快?

时间:2019-12-01 16:08:20

标签: python concurrency

我正在处理图像,并且其像素的大小为1920x1200(可能因图像而异)。我正在遍历每个像素,并根据不同的条件增加一些全局变量。因此,我现在基本上有了一个嵌套的for循环,可用于遍历像素。

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';

@Injectable()
export class AuthService {
  constructor(
    private readonly service: AngularFireAuth
  ) {}

  public login(credentials: Credentials): Promise<any> {
    const { email, password } = credentials;
    return this.service.auth.signInWithEmailAndPassword(email, password);
  }

  public isLoggedIn(): Promise<boolean> {
    return new Promise((resolve: any) => {
      this.service.auth.onAuthStateChanged(( user: any ) => {
        user ? resolve(true) : resolve(false);
      });
    });
  }
}

variable1 = 0  #variables declared globally
variable2 = 0

# this method gets a pixel and increases some global variables if the conditions are met
def mapp(pixel):
    global variable1
    global variable2

    if(condition):
        variable1 = variable1 + 1
        return
    if(condition2):
        variable2 = variable2 + 1
        return

我想使其并发,以便 X 进程可以同时运行,而每个进程仅处理图像的 1 / X ,从而使程序运行得更快。我该怎么办?


拥有全局变量是一种好习惯吗?在尝试使程序并发时是否有可能在每次迭代时都增加全局变量?是否有更好的方法?如果是这样,那是什么方法,我该怎么做?在这种情况下有什么地方可能出问题吗? (我对Python和整体并发还很陌生)

1 个答案:

答案 0 :(得分:0)

存在与并行性和不同类型的并行性相关的成本。如评论中所建议,我将研究多处理和多线程。两者之间的主要区别在于,当不进行多处理时,线程将受制于GIL(全局解释器锁定)。

就全局变量而言,通常最好使用局部变量,因为对它们的访问更快,但是全局变量确实在编程中占有一席之地。在您的情况下,我不会使用全局变量。相反,您可以使用局部变量并执行类似归约的操作。

在并行方面,一个简单的解决方案是使用多处理池,但是请注意,此选项会产生开销。

import multiprocessing as mp
import numpy as np

variable1 = 0
variable2 = 0

def mapp(pixel):
    if(pixel==1):
        return 0
    if(pixel==2):
        return 1

if __name__ == "__main__":

    X = 4 #number of processes
    #Example array
    exampleShape = (10,10)
    exampleArray = np.ones(exampleShape)
    reshapedArray = np.reshape(exampleArray,exampleShape[0]*exampleShape[1])
    for i in range(0,len(reshapedArray),3):
        reshapedArray[i] = 2
    #create pool
    myPool = mp.Pool(X)
    res = myPool.map(mapp,reshapedArray)
    #Reduction
    resSum = sum(res)
    variable1 += resSum
    variable2 += abs(len(res)-resSum)
    #close pool
    myPool.close()