Я использую 36-ядерный узел HPC. Спецификация заключается в том, что узел имеет 2 процессора Intel Xeon E5-2695 v4 с 18 ядрами каждый. Я пытаюсь записать карту памяти из основного процесса, а подпроцесс считывает карту памяти и обновляет ее. Подпроцесс некоторое время спит перед обновлением. Я запускаю несколько подпроцессов параллельно.
Я проводил некоторое тестирование производительности и столкнулся со сценарием, который я объяснил ниже в результатах своего кода.
import time
from mmap import mmap
from multiprocessing import Process, Lock
f = open("results.csv", "w")
f.write("mmap_time,total_time\n")
def sub_process(m, mutex):
while True:
mutex.acquire()
if m[0] == 72: # equivalent to H
time.sleep(0.001) # sleep for 1 millisecond
m.seek(0)
m.write(bytes("child", "utf-8"))
mutex.release()
time.sleep(0.00001)
n = 80 #Num of Subprocess
m = []
mutex = []
process = []
for i in range(n):
m.append(mmap(-1, 5))
mutex.append(Lock())
process.append(Process(target = sub_process, args = (m[i], mutex[i])))
process[i].start()
for it in range(100):
total_start_time = time.time_ns() / (10 ** 6) # milliseconds time
mmap_dict = {}
for i in range(n):
mmap_dict[m[i]] = mutex[i]
for mmap,mu in mmap_dict.items():
mu.acquire()
mmap.seek(0)
mmap.write(bytes("Hello", "utf-8"))
mu.release()
condition = True
mmap_start_time = time.time_ns() / (10 ** 6)
while condition:
l = [] # list to hold the mmap that were updated
for mmap,mu in mmap_dict.items():
mu.acquire()
mmap.seek(0)
if mmap[0] == 99: # equivalent to c
l.append(mmap)
mu.release()
for mmap in l:del mmap_dict[mmap]
if len(mmap_dict) == 0:
del mmap_dict
condition = False
mmap_end_time = time.time_ns() / (10 ** 6)
total_end_time = time.time_ns() / (10 ** 6)
f.write(str(mmap_end_time - mmap_start_time) + "," + str(total_end_time - total_start_time) + "\n")
f.close()
for i in range(n):
process[i].terminate()
m[i].close()
В каждом подпроцессе, когда он обнаруживает, что его карта памяти обновляется. Подпроцесс спит в течение 1 миллисекунды, а затем обновляет карту памяти.
Выходные данные были следующими (все значения времени являются средними значениями 100 итераций и указаны в миллисекундах):
|---------------------|-----------------|-----------------|
| Num_Subprocess | mmap_time | total_time |
|---------------------|-----------------|-----------------|
| 1 | 1.122416992 | 1.126069336 |
|---------------------|-----------------|-----------------|
| 10 | 1.115305176 | 1.130327148 |
|---------------------|-----------------|-----------------|
| 40 | 1.133754883 | 1.212219238 |
|---------------------|-----------------|-----------------|
| 80 | 1.172145996 | 1.350251465 |
|---------------------|-----------------|-----------------|
Я понимаю, что время mmap находится в диапазоне 1,1, потому что я записываю только время, необходимое для того, чтобы основной процесс увидел отражение. Но для 40 подпроцессов я ожидаю, что общее время составит не менее 2 миллисекунд, так как я сплю 1 миллисекунду в подпроцессе, а у меня всего 36 ядер, а для 80 подпроцессов я ожидаю не менее 3 миллисекунд. Может кто-нибудь объяснить, почему общее время ниже ожидаемого значения? Есть ли ошибка в моем коде?