最近开始自学并行,我几乎不知道自己在做什么。尝试应用我学到的东西,但我认为我做错了什么,因为我的并行代码比串行代码执行时间更长。我的电脑正在运行i7-9700。这是有问题的原始序列码
def getMatrix(name):
matrixCreated = []
i = 0
while True:
i += 1
row = input('nEnter elements in row %s of Matrix %s (separated by commas)nOr -1 to exit: ' %(i, name))
if row == '-1':
break
else:
strList = row.split(',')
matrixCreated.append(list(map(int, strList)))
return matrixCreated
def getColAsList(matrixToManipulate, col):
myList = []
numOfRows = len(matrixToManipulate)
for i in range(numOfRows):
myList.append(matrixToManipulate[i][col])
return myList
def getCell(matrixA, matrixB, r, c):
matrixBCol = getColAsList(matrixB, c)
lenOfList = len(matrixBCol)
productList = [matrixA[r][i]*matrixBCol[i] for i in range(lenOfList)]
return sum(productList)
matrixA = getMatrix('A')
matrixB = getMatrix('B')
rowA = len(matrixA)
colA = len(matrixA[0])
rowB = len(matrixB)
colB = len(matrixB[0])
result = [[0 for p in range(colB)] for q in range(rowA)]
if (colA != rowB):
print('The two matrices cannot be multiplied')
else:
print('nThe result is')
for i in range(rowA):
for j in range(colB):
result[i][j] = getCell(matrixA, matrixB, i, j)
print(result[i])
编辑:这是带有时间库的并行代码。最初没有包括它,因为我认为它是错误的,所以我只想看看是否有人有想法将其并行化,而不是
import multiprocessing as mp
pool = mp.Pool(mp.cpu_count())
def getMatrix(name):
matrixCreated = []
i = 0
while True:
i += 1
row = input('nEnter elements in row %s of Matrix %s (separated by commas)nOr -1 to exit: ' %(i, name))
if row == '-1':
break
else:
strList = row.split(',')
matrixCreated.append(list(map(int, strList)))
return matrixCreated
def getColAsList(matrixToManipulate, col):
myList = []
numOfRows = len(matrixToManipulate)
for i in range(numOfRows):
myList.append(matrixToManipulate[i][col])
return myList
def getCell(matrixA, matrixB, r, c):
matrixBCol = getColAsList(matrixB, c)
lenOfList = len(matrixBCol)
productList = [matrixA[r][i]*matrixBCol[i] for i in range(lenOfList)]
return sum(productList)
matrixA = getMatrix('A')
matrixB = getMatrix('B')
rowA = len(matrixA)
colA = len(matrixA[0])
rowB = len(matrixB)
colB = len(matrixB[0])
import time
start_time = time.time()
result = [[0 for p in range(colB)] for q in range(rowA)]
if (colA != rowB):
print('The two matrices cannot be multiplied')
else:
print('nThe result is')
for i in range(rowA):
for j in range(colB):
result[i][j] = getCell(matrixA, matrixB, i, j)
print(result[i])
print (" %s seconds " % (time.time() - start_time))
results = [pool.apply(getMatrix, getColAsList, getCell)]
pool.close()
所以我同意你做错了什么。我想说你的代码是不可并行的。
为了使代码可并行,必须将其划分为更小的部分,并且必须是:
1,独立,这意味着当它运行时,它不依赖其他进程来完成它的工作。
例如,如果我有一个包含1000000个需要处理的对象的列表。我有4个工人来处理它们。然后给每个工人1/4的对象进行处理,然后当他们完成所有对象的处理时。但是工作人员3不在乎工作人员1、2或4是在完成之前完成还是之后完成。工人3也不关心工人1、2或4返回或做了什么。事实上,它甚至不应该知道还有其他工人在那里。
2,Managed,这意味着工作人员之间存在依赖关系,但这没关系,因为您有一个协调工作人员的主线程。尽管如此,工人们不应该相互了解或关心。把他们想象成无意识的肌肉,他们只做你让他们做的事,而不是自己思考。
例如,我有一个包含1000000个需要处理的对象的列表。首先,所有对象都需要经过func1
,它返回一些东西。一旦用func1
完成了所有对象,这些结果就应该进入func2
。因此,我创建了4个工作者,给每个工作者1/4的对象,让他们用func1
处理它们并返回结果。我等待所有工人完成对对象的处理。然后,我将func1
返回的结果的1/4给每个工作人员,并让他们用func2
进行处理。我可以随心所欲地做这件事。我所要做的就是让主线程协调工人,这样他们就不会在没有假设的时候开始,并告诉他们什么时候处理。
对此持保留态度,因为这是并行处理的简化版本。
并行和并发提示
您不应该并行地获得用户输入。只有主线程才能处理这个问题。
如果你的工作量很轻,那么你就不应该使用并行处理。
如果你的任务不能分成更小的部分,那么它就不可平行。但它仍然可以在后台线程上运行,作为同时运行某些东西的一种方式。
并发示例:
如果你的任务是长时间的并且不可并行,比如说需要10分钟才能完成。它需要用户提供输入。然后,当用户给出输入时,在工作者上启动任务。如果用户在1分钟后再次输入,那么接受该输入并在worker2上启动第二个任务。输入时间为5分钟,在worker3上启动task3。10分钟后,任务1完成。因为在15分钟之前所有的事情都在同时运行,所以所有的任务都完成了。这比串行运行需要30分钟的任务快2倍。然而,这是并发性而非并行性。