Я хочу зашифровать список из 300 чисел, используя гомоморфное (paillier) шифрование. Это занимает примерно 3000 мс на моем ноутбуке, намного больше на моем малиновом пи. Я хотел бы ускорить это, поэтому я попытался использовать многопоточность:
from multiprocessing.dummy import pool as ThreadPool
def test_1_performance_of_encryption(self):
print("Test: Blind encryption performance test")
print("-----------------------------")
print()
# Only blinds are encrypted
for y in range(0, ((NUMBER_OF_RUNS//SENSOR_SAMPLES_PER_BLIND)*NUM_OF_DATA_PROCESSORS)):
print("Round {}:".format(y+1))
print("Encrypting {} blinds...".format(NUM_OF_SENSOR_SAMPLES))
encrypted_blinds.clear()
millis_start = int(round(time.time() * 1000))
for x in range(0, NUM_OF_SENSOR_SAMPLES):
encrypted_blinds.append(public_keys[0].encrypt(blinds[x]))
millis_end = int(round(time.time() * 1000))
time_elapsed_enc.append(millis_end - millis_start)
print("Time elapsed: {}ms".format(time_elapsed_enc[y]))
print("Test finished. Time elapsed:")
print("Min: {} | Max: {} | Avg: {}".format(min(time_elapsed_enc), max(time_elapsed_enc),
(sum(time_elapsed_enc)/len(time_elapsed_enc))))
print()
@profile
def test_1a_performance_of_encryption_multithreaded(self):
print("Test: Blind encryption performance test with {} threads".format(NUM_OF_THREADS))
for y in range(0, ((NUMBER_OF_RUNS//SENSOR_SAMPLES_PER_BLIND)*NUM_OF_DATA_PROCESSORS)):
print("Round {}:".format(y+1))
print("Encrypting {} blinds...".format(len(blinds)))
millis_start = int(round(time.time() * 1000))
encrypted_blinds_multithreaded = pool.map(public_keys[0].encrypt, blinds)
millis_end = int(round(time.time() * 1000))
time_elapsed_enc_multithread.append(millis_end - millis_start)
print("Time elapsed: {}ms".format(time_elapsed_enc_multithread[y]))
print("Test finished. Time elapsed:")
print("Min: {} | Max: {} | Avg: {}".format(min(time_elapsed_enc_multithread), max(time_elapsed_enc_multithread),
(sum(time_elapsed_enc_multithread) / len(time_elapsed_enc_multithread))))
print()
Однако оба теста заканчиваются примерно в одно и то же время. В то время как однопоточный метод использует одно ядро на 100%, многопоточная версия использует их все, но все равно создает нагрузку, равную 1 (равно 1 ядру на 100%). Я что-то здесь не так делаю? Я прочитал этот вопрос, и он отвечает: Python multiprocessing.Pool () не использует 100% каждого процессора , однако я не верю, что причина здесь в межпроцессном взаимодействии, поскольку это было бы очень странно что он устанавливается точно при нагрузке 1 ...
EDIT : я использовал multiprocessing.dummy
вместо multiprocessing
. Я думаю, что здесь использовались несколько потоков вместо процессов, и несколько потоков не могут выполняться параллельно в Python из-за того, что называется GIL (глобальная блокировка интерпретатора). Я исправил это, изменив multiprocessing.dummy
на multiprocessing
. У меня сейчас n процессов и загрузка процессора 100%.