为什么并行任务总是在第一次变慢?

时间:2017-12-19 15:30:13

标签: python bash parallel-processing joblib

我想要在一个样本上评估一些分类器。此任务可以并行运行,因为它们彼此独立。这意味着我想并行化它。

我用python和bash脚本尝试过它。问题是,当我第一次运行程序时,需要30s-40s才能完成。当我连续多次运行程序时,只需1s-3s即可完成。即使我输入了具有不同输入的分类器,我得到了不同的结果,因此似乎没有缓存。当我运行其他程序然后重新运行程序时,它再次需要40秒才能完成。

我还在htop中观察到,当程序第一次运行时CPU没有那么多用,但是当我再次重新运行它时,CPU被充分利用。

有人可以解释一下这种奇怪的行为吗?如何避免它,以便即使第一次运行程序也会很快?

这是python代码:

import time
import os
from fastText import load_model
from joblib import delayed, Parallel, cpu_count
import json

os.system("taskset -p 0xff %d" % os.getpid())

def format_duration(start_time, end_time):
    m, s = divmod(end_time - start_time, 60)
    h, m = divmod(m, 60)
    return "%d:%02d:%02d" % (h, m, s)

def classify(x, classifier_name, path):
    f = load_model(path + os.path.sep + classifier_name)    
    labels, probabilities = f.predict(x, 2)
    if labels[0] == '__label__True':
        return classifier_name
    else:
        return None

if __name__ == '__main__':
    with open('classifier_names.json') as json_data:
        classifiers = json.load(json_data)
    x = "input_text"

    Parallel(n_jobs=cpu_count(), verbose=100, backend='multiprocessing', pre_dispatch='all') \
        (delayed(perform_binary_classification)
         (x, classifier, 'clfs/') for
         classifier in classifiers)

    end_time = time.time()
    print(format_duration(start_time, end_time))

这是bash代码:

#!/usr/bin/env bash
N=4
START_TIME=$SECONDS
open_sem(){
    mkfifo pipe-$$
    exec 3<>pipe-$$
    rm pipe-$$
    local i=$1
    for((;i>0;i--)); do
        printf %s 000 >&3
    done
}
run_with_lock(){
    local x
    read -u 3 -n 3 x && ((0==x)) || exit $x
    (
    "$@" 
    printf '%.3d' $? >&3
    )&
}
open_sem $N
for d in classifiers/* ; do
    run_with_lock ~/fastText/fasttext predict "$d" test.txt 
done

ELAPSED_TIME=$(($SECONDS - $START_TIME))
echo time taken $ELAPSED_TIME seconds

EDITED

更大的图片是我正在使用2种API方法运行烧瓶应用程序。他们每个人都调用并行化分类的功能。当我做请求时,它的行为与下面的程序相同。对方法A的第一次请求需要很多,然后后续请求需要1s。当我切换到方法B时,它与方法A的行为相同。如果我在方法A和方法B之间多次切换,如A,B,A,B,则每个请求需要40秒才能完成。

0 个答案:

没有答案