我想要在一个样本上评估一些分类器。此任务可以并行运行,因为它们彼此独立。这意味着我想并行化它。
我用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秒才能完成。