Content deleted Content added
Improve wording, formatting, and clarity. Ensure 'code' is used as an uncountable noun. |
|||
(34 intermediate revisions by 22 users not shown) | |||
Line 1:
{{no footnotes|date=November 2023}}
In [[computer science]], '''run-time algorithm specialization''' is a methodology for creating efficient algorithms for costly computation tasks of certain kinds. The methodology originates in the field of [[automated theorem proving]] and, more specifically, in the [[Vampire theorem prover]] project.
The idea is inspired by the use of [[partial evaluation]] in optimising program translation.
Many core operations in theorem provers exhibit the following pattern.
Suppose that we need to execute some algorithm <math>\mathit{alg}(A,B)</math> in a situation where a value of <math>A</math> ''is fixed for potentially many different values of'' <math>B</math>. In order to do this efficiently, we can try to find a specialization of <math>\mathit{alg}</math> for every fixed <math>A</math>, i.e., such an algorithm <math>\mathit{alg}_A</math>, that executing <math>\mathit{alg}_A(B)</math> is equivalent to executing <math>\mathit{alg}(A,B)</math>.
The specialized algorithm may be more efficient than the generic one, since it can ''exploit some particular properties'' of the fixed value <math>A</math>. Typically, <math>\mathit{alg}_A(B)</math> can avoid some operations that <math>\mathit{alg}(A,B)</math> would have to perform, if they are known to be redundant for this particular parameter <math>A</math>.
In particular, we can often identify some tests that are true or false for <math>A</math>, unroll loops and recursion, etc.
The key difference between run-time specialization and partial evaluation is that the values of <math>A</math> on which <math>\mathit{alg}</math> is specialised are not known statically, so the ''specialization takes place at run-time''.
There is also an important technical difference. Partial evaluation is applied to algorithms explicitly represented as codes in some programming language. At run-time, we do not need any concrete representation of <math>\mathit{alg}</math>. We only have to ''imagine'' <math>\mathit{alg}</math> ''when we program'' the specialization procedure.
All we need is a concrete representation of the specialized version <math>\mathit{alg}_A</math>. This also means that we cannot use any universal methods for specializing algorithms, which is usually the case with partial evaluation. Instead, we have to program a specialization procedure for every particular algorithm <math>\mathit{alg}</math>. An important advantage of doing so is that we can use some powerful ''ad hoc'' tricks exploiting peculiarities of <math>\mathit{alg}</math> and the representation of <math>A</math> and <math>B</math>, which are beyond the reach of any universal specialization methods.
==Specialization with compilation==
The specialized algorithm has to be represented in a form that can be interpreted.
In many situations, usually when <math>\mathit{alg}_A(B)</math> is to be computed on many values of <math>B</math> in a row, <math>\mathit{alg}_A</math> can be written as machine code instructions for a special [[abstract machine]], and it is typically said that <math>A</math> is ''compiled''. The code itself can then be additionally optimized by answer-preserving transformations that rely only on the semantics of instructions of the abstract machine.
The instructions of the abstract machine can usually be represented as [[Record (computer science)|record]]s. One field of such a record, an ''instruction identifier'' (or ''instruction tag''), would identify the instruction type, e.g. an [[Integer (computer science)|integer]] field may be used, with particular integer values corresponding to particular instructions. Other fields may be used for storing additional parameters of the instruction, e.g. a [[Pointer (computer programming)|pointer]] field may point to another instruction representing a label, if the semantics of the instruction require a jump. All instructions of the code can be stored in a traversable [[data structure]] such as an [[Array (data type)|array]], [[linked list]], or [[Tree (abstract data type)|tree]].
''Interpretation'' (or ''execution'') proceeds by fetching instructions in some order, identifying their type, and executing the actions associated with said type.
In many programming languages, such as [[C (programming language)|C]] and [[C++]], a simple [[Switch statement|<code>switch</code> statement]] may be used to associate actions with different instruction identifiers. Modern compilers usually compile a <code>switch</code> statement with constant (e.g. integer) labels from a narrow range by storing the address of the statement corresponding to a value <math>i</math> in the <math>i</math>-th cell of a special array, as a means of efficient optimisation. This can be exploited by taking values for instruction identifiers from a small interval of values.
==Data-and-algorithm
There are situations when many instances of <math>A</math> are intended for long-term storage and the calls of <math>\mathit{alg}(A,B)</math> occur with different <math>B</math> in an unpredictable order.
In such circumstances, full-scale specialization with compilation may not be suitable due to excessive memory usage.
However, we can sometimes find a compact specialized representation <math>A^{\prime}</math>
for every <math>A</math>, that can be stored with, or instead of, <math>A</math>.
We also define a variant <math>\mathit{alg}^{\prime}</math> that works on this representation
and any call to <math>\mathit{alg}(A,B)</math> is replaced by <math>\mathit{alg}^{\prime}(A^{\prime},B)</math>, intended to do the same job faster.
== See also ==
* [[Psyco]], a specializing run-time compiler for [[Python (programming language)|Python]]
* [[multi-stage programming]]
==
* [https://doi.org/10.1007%2FBF00881918 A. Voronkov, "The Anatomy of Vampire: Implementing Bottom-Up Procedures with Code Trees", ''Journal of Automated Reasoning'', 15(2), 1995] (''original idea'')
==Further reading==
* A. Riazanov and [[Andrei Voronkov|A. Voronkov]], "Efficient Checking of Term Ordering Constraints", ''Proc. [[IJCAR]]'' 2004, Lecture Notes in Artificial Intelligence 3097, 2004 (''compact but self-contained illustration of the method'')
* A. Riazanov and A. Voronkov, [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.57.8542 Efficient Instance Retrieval with Standard and Relational Path Indexing], [[Information and Computation]], 199(1-2), 2005 (''contains another illustration of the method'')
* A. Riazanov, [http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.2624 "Implementing an Efficient Theorem Prover"], PhD thesis, The University of Manchester, 2003 (''contains the most comprehensive description of the method and many examples'')
[[Category:Algorithms]]
[[Category:Software optimization]]
|