I am trying to understand concurrent.futures so i wanted to create a small code example. The numbers from 1 to $10^7$ shall be summed up. I want to use 4 cores. So I created 4 lists, namely [1,5,9,13...], [2,6,10,14...], [3,7,11,...], [4,8,12,...].
But when I run my script and check the system monitor (Linux Mint 21) I see, that only one core is used. Shouldn't it be four?
Here is my code:
#!/usr/bin/python3
from multiprocessing import Pool
import time
import concurrent.futures
def computeSum(list):
sumValue = 0
for i in list:
sumValue += i
return sumValue
def computeModuloList(completeList, modulo, moduloOffset):
# empty list
moduloList = []
for i in completeList:
if i % modulo - moduloOffset == 0:
moduloList.append(i) # append i to modulo list
return moduloList
listToSum = range(1, 10**7+1)
partialList1 = computeModuloList(listToSum, 4, 0)
partialList2 = computeModuloList(listToSum, 4, 1)
partialList3 = computeModuloList(listToSum, 4, 2)
partialList4 = computeModuloList(listToSum, 4, 3)
partialLists = [partialList1, partialList2, partialList3, partialList4]
resultList = []
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
future = {executor.submit(computeSum, pList): pList for pList in partialLists}
for completedFuture in concurrent.futures.as_completed(future):
resultList.append(completedFuture.result())
allSum = 0
for result in resultList:
allSum += result
print(str(allSum))
I checked the system monitor and only one core is used
I would go down the multiprocessing
rout, but do note the answer from Codist which uses concurrent.futures
.
This is what multiprocessing would look like for the same:
from multiprocessing import Pool
import numpy as np
def main():
n = 10**7
arr = np.arange(1, n+1)
# Split into 4 arrays
arr1, arr2, arr3, arr4 = np.array_split(arr, 4)
with Pool(4) as pool:
res1 = pool.apply_async(sum_array, [arr1])
res2 = pool.apply_async(sum_array, [arr2])
res3 = pool.apply_async(sum_array, [arr3])
res4 = pool.apply_async(sum_array, [arr4])
sums = [r.get() for r in [res1, res2, res3, res4]]
total = sum(sums)
print(total)
def sum_array(arr):
return np.sum(arr, dtype=np.uint64)
if __name__ == '__main__':
main()
the code returns this:
50000005000000.0
As a side note. I ran both methods up to 10^9 and multiprocessing
was meaningfully faster (in fact concurrent.futures
hung my PC).