我正在测试我的smt模型使用不同的求解器。此时,我有一个文件.smt2,其中包含在smtlib中转换的模型的指令。
我创建了一个.sh文件,它实现了线性搜索,以便使用不同的求解器测试我的模型。
这是我的bash文件的代码:
#!/bin/bash
# Usage:
# ./smt-opt <SMT-LIB file> <obj.var name> <initial bound> <solver> <min/max>
# No (get-model) query should in the SMT-LIB input file.
TIMEOUT=300 # Timeout in seconds. TODO: Set timeout as a parameter.
in_file=$1
obj_var=$2
obj_val=$3
if
[ "$4" = 'z3' ];
then
solver_cmd="z3 -in "
elif
[ "$4" = 'cvc4' ];
then
solver_cmd="cvc4 --lang smt --produce-models --incremental "
elif
[ "$4" = 'cvc5' ];
then
solver_cmd="cvc5 --produce-models --incremental "
else
echo "Unknown solver!"
exit 1
fi
if [ "$5" = 'max' ]; then
# Maximization problem.
rel='>='
next=1
else
# Minimization problem.
rel='<='
next=-1
fi
# Creating input/output pipes.
in_pipe=pipe.in
out_pipe=pipe.out
rm $in_pipe $out_pipe pkill sleep 2>/dev/null
mkfifo $in_pipe
mkfifo $out_pipe
# Block input pipe for $TIMEOUT seconds.
sleep $TIMEOUT > $in_pipe &
# Send piped input data to solver, and the output of solver to output pipe.
$solver_cmd < $in_pipe > $out_pipe &
# Feed input pipe with the queries SMT-LIB specified in the input file.
cat $in_file > $in_pipe
# SOL = 0 iff solver hasn't find any solution yet.
SOL=0
while read line < $out_pipe
do
if [ ! "$line" = 'sat' ]; then
break;
fi
SOL=1
echo -e "$obj_var = $obj_val\n----------"
# Updating obj. value (linear search). TODO: Implement binary search.
obj_val=`awk -v ov=$obj_val -v n=$next 'BEGIN {ov = int(ov) + n; print ov}'`
if
[ $obj_val -lt 0 ]
then
# Adjusting for unary minus.
echo "(assert ($rel $obj_var (-"`echo $obj_val | tr '-' ' '`")))" > $in_pipe
else
echo "(assert ($rel $obj_var $obj_val))" > $in_pipe
fi
echo "(check-sat)" > $in_pipe
# echo "%%% Solving with $obj_var $rel $obj_val"
done
if
[[ $SOL -eq 0 ]]
then
if [ "$line" = 'unsat' ]; then
echo '=====UNSATISFIABLE====='
else
echo '=====UNKNOWN====='
fi
elif [ "$line" = 'unsat' ]; then
echo '=========='
fi
rm $in_pipe $out_pipe pkill sleep 2>/dev/null
具体来说,我的问题是在这一行:
cat $in_file > $in_pipe
这个指令的问题是它需要很多时间(我的smtlib文件的维度是80兆字节)。我如何替换此指令以获得更有效的指令?
我期待着一个更有效的指令,为这个项目的工作。
1条答案
按热度按时间zdwk9cvp1#
cat
不是性能问题。真的不是管道输出端的东西比输入端的东西慢得多;假设I/O性能合理,则
cat
在等待solver_cmd
运行时挂起,而solver_cmd
很可能在等待read
运行时挂起。(请记住,管道的所有部分都是并行运行的,并且管道缓冲区的大小是有限的--一旦管道满了,就不能在输入端写入任何内容,直到从输出端拉出一些内容)。...但是你可以在你的输入文件中直接用一个句柄替换它。
而不是试图取代
cat
的东西,做一个更快的复制从一个文件到一个FIFO,我们可以只attech您的求解过程 * 直接到文件 *,而不是试图使用任何FIFO在所有。注意
<"$in_file"
--不需要mkfifo
或cat
。这将快得多,特别是当您的求解器可以利用输入上的可查找文件描述符来并行读取输入流的多个部分并将它们交给不同的线程或子进程时;否则这将是一个相当大的边际改进。如果遇到死锁,这些都没有用
看起来你的代码确实有一个。
请记住,一次只能有一个进程写入FIFO:如果
cat
正在向其中写入,则echo
不能。如果cat
在echo
完成之前不能完成(因为你的流水线的输出端在echo
完成时阻塞,并且有足够的数据填充管道缓冲区,所以求解器在echo
完成之前不能写入更多的内容),那么你的程序永远不会完成。