Используя IronPython, я вызываю некоторую функцию параллельно, которая находится внутри той же функции, в которой находятся распараллеленные данные, чтобы сохранить их в той же области видимости.
В многопроцессорной обработке CPython совершенно очевидно, что данные должны явно передаваться подпроцессу, сколько подпроцессов открыто и т. Д. Это позволяет легко понять издержки.
В случае PLINQ, как код выполняется параллельно? I.E.:
Есть ли еще один экземпляр ironpython, который запускается и все снова импортируется? Например, import myHugeLibrary
будет запускаться каждый раз, когда из файла создается новый экземпляр python.
CalcParallel()
принимает некоторые массивы данных и словарь. В этой области находится функция computation()
, которая должна выполняться параллельно, и она вызывает другую функцию checkVals()
в основном скрипте. Поскольку computation()
находится в той же области, в которой вызывается AsParallel()
, мне не нужно явно передавать ему данные, которые будут использоваться. Однако означает ли это, что данные копируются в каждый процесс / поток или хранятся в качестве ссылки, и это нормально, когда они только читаются (не записываются)? Если он копируется, копируется ли он каждый раз при вычислении элемента, то есть, если в списке 100 элементов и 10 потоков, будет ли он копировать данные 10 раз, поскольку он помещает 100 элементов в 10 блоков, или копирует 100 раз
Аналогично, пример данных C_dict модифицируется после вычисления некоторого количества данных и перед запуском следующего раунда данных (на основе результатов он добавляет больше вещей). Затем эти измененные данные копируются снова при запуске параллельного процесса?
Ниже приведен пример структуры кода, который мне интересен. Дело не в самом коде, но я написал это, чтобы проиллюстрировать вопрос, даже если это не совсем правильно.
# get LINQ dependencies
import clr
clr.AddReference("System.Core")
import System
clr.ImportExtensions(System.Linq)
from System.Threading.Tasks import *
#import some huge library that takes time
import myHugeLibrary
max_val = 4 #some global value used within the thread
def checkVals(itemToCheck,A_vals,B_vals):
#check against some global value
if itemToCheck < max_val:
return 0
#do something else with A_vals
def CalcParallel(todo_list,A_vals,B_vals,C_dict):
"""
take in some data that is used in the functions that will
run in parallel.
"""
total_list = []
#make a function that will be run in parallel
def computation(itemToCheck):
checkedItems = checkVals(itemToCheck,A_vals,B_vals)
results = []
for item in checkedItems:
results.append(item)
return results
#in a loop keep sending something out for calculation in parallel until
# all the combinations are done
while len(todo_list) != 0:
#use AsParallel on a list of items
results = todo_list.AsParallel().SelectMany(
lambda itemToCheck:
computation(itemToCheck) ).ToList()
todo_list = []
for item in results:
if item not in total_list:
total_list.append(item)
#do some modification to the dictionary that was passed in
C_dict[item] = None
return total_list
def main():
todo_list = [3,3,2,4,5,4,1,3,4,5,1]
A_vals = [0,1,2,3,4,5,6]
B_vals = [-1,-3,-5,-7,-9]
C_dict = {0:-3,4:-7}
newVals = CalcParallel(todo_list,A_vals,B_vals,C_dict)
print(newVals)
main()