Я создал backtester в python, который выполняет полный цикл за 70 мс. В одном потоке (используя для l oop) я могу запустить этот backtester, и он показывает нормальную производительность (около 70 мс на итерацию):
for q in queue:
print(backtest(alldata1h, alldata, q['strats'], q['filts']))
Моя проблема заключается в следующем: всякий раз, когда я пытаюсь Запустите эту функцию, используя многопроцессорность, производительность будет намного хуже (~ 800 мс на тестирование на истории).
Я пытался сделать это, используя массив объектов Process
и Queue
:
def do_workload(q, wk, a1h, ad):
for w in wk:
c = backtest(a1h, ad, w['strats'], w['filts'])
q.put({"Strategy": w['sname'], "Filter": w['fname'], "c": c})
q.put('DONE')
#Please ignore unnecessary indentation
for i in range(thread_nr):
thread_pool.append({"Process": "", "Queue": "", "workload": workloads[i], "workindex": 0, "finished": False})
thread_pool[i]['Queue'] = Queue()
thread_pool[i]['Process'] = Process(target=do_workload, args=(thread_pool[i]['Queue'], workloads[i], alldata1h, alldata))
thread_pool[i]['Process'].start()
print("Total workload: {} backtests".format(len(queue)))
while queue_index < len(queue):
for t in range(len(thread_pool)):
time.sleep(0.1)
if thread_pool[t]['finished'] == False:
while not thread_pool[t]['Queue'].empty():
res = thread_pool[t]['Queue'].get()
if res == "DONE":
thread_pool[t]['finished'] = True
else:
final_results = final_results.append(res, ignore_index=True)
queue_index += 1
print("Read from threads: {}/{}".format(queue_index, len(queue)))
time.sleep(10)
print("DONE")
, и я также попробовал это, используя объект Pool
:
print("Total workload: {} backtests".format(len(queue)))
from functools import partial
target = partial(do_workload, a1h=alldata1h, ad=alldata)
pool = Pool(processes=thread_nr)
print("Starting pool...")
print(len(pool.map(target, workloads, len(workloads[0]))))
Мой процессор имеет 64 ядра и 128 потоков, поэтому я дал ему высокое значение thread_nr
(около 100-120), но производительность по-прежнему ужасна.
Мой вопрос заключается в следующем: есть ли способ улучшить python достаточную многопроцессорность, чтобы достичь 70 мс на тестирование на секунду (на процесс)? Или я должен переписать весь проект (backtester и менеджер процессов) на C ++, чтобы добиться максимальной производительности (используя все возможные потоки / весь процессор).