# source:docs/EuroPar2011/europar-cameron.tex@4550

Last change on this file since 4550 was 1302, checked in by lindanl, 8 years ago

Create a directory for HPCA

File size: 44.1 KB
RevLine
[879]1
[893]2
[879]3%%%%%%%%%%%%%%%%%%%%%%% file typeinst.tex %%%%%%%%%%%%%%%%%%%%%%%%%
4%
5% This is the LaTeX source for the instructions to authors using
6% the LaTeX document class 'llncs.cls' for contributions to
7% the Lecture Notes in Computer Sciences series.
8% http://www.springer.com/lncs       Springer Heidelberg 2006/05/04
9%
10% It may be used as a template for your own input - copy it
11% to a new file with a new name and use it as the basis
13%
14% NB: the document class 'llncs' has its own and detailed documentation, see
15% ftp://ftp.springer.de/data/pubftp/pub/tex/latex/llncs/latex2e/llncsdoc.pdf
16%
17%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
18
19
21\usepackage{multirow}
22\usepackage{amssymb}
23\setcounter{tocdepth}{3}
24\usepackage{graphicx}
25
26\usepackage{url}
27\urldef{\mailsa}\path|{alfred.hofmann, ursula.barth, ingrid.haas, frank.holzwarth,|
28\urldef{\mailsb}\path|anna.kramer, leonie.kunz, christine.reiss, nicole.sator,|
29\urldef{\mailsc}\path|erika.siebert-cole, peter.strasser, lncs}@springer.com|
31\noindent\keywordname\enspace\ignorespaces#1}
32
33\begin{document}
34
35\mainmatter  % start of an individual contribution
36
37
38
39
40% first the title is needed
41\title{Parallel Scanning with Bitstream Addition: An XML Case Study}
42
43% a short form should be given in case it is too long for the running head
45
46% the name(s) of the author(s) follow(s) next
47%
48% NB: Chinese authors should write their first names(s) in front of
49% their surnames. This ensures that the names appear correctly in
50% the running heads and the author index.
51%
52\author{Robert D. Cameron
53\and Ehsan Amiri \and Kenneth S. Herdy \and Dan Lin \and Thomas C. Shermer \and Fred P. Popowich}
54
55%
[1186]56\authorrunning{Cameron, Amiri, Herdy, Lin, Shermer and Popowich}
58% unless you accept that it will be published
59\institute{Simon Fraser University, Surrey, BC, Canada\\
60\email{\{cameron, eamiri, ksherdy, lindanl, shermer, popowich\}@cs.sfu.ca}
61}
62
63\maketitle
64
65
66\begin{abstract}
67A parallel scanning method using the concept of bitstream addition is
68introduced and studied in application to the problem of XML
69parsing and well-formedness checking.
70% The method parallelizes
71% finite-state transitions, using carry propagation to achieve up
72% to $W$ transitions with each $W$-bit binary addition operation.
73On processors supporting $W$-bit addition operations,
[883]74the method can perform up to $W$ finite state transitions per instruction.
[879]75The method is based on the concept of parallel bitstream technology,
76in which parallel streams of bits are formed such that each stream
77comprises bits in one-to-one correspondence with the character
78code units of a source data stream.    Parsing routines are initially
79prototyped in Python using its native support for unbounded
80integers to represent arbitrary-length  bitstreams.  A compiler
81then translates the Python code into low-level C-based implementations.
82These low-level implementations take advantage of
83the SIMD (single-instruction multiple-data) capabilities of commodity
84processors to yield a dramatic speed-up over
[893]86%\keywords{SIMD text processing, parallel bitstream technology, XML, parsing}
87\keywords{SIMD text processing, parallel bitstreams, XML, parsing}
[879]88\end{abstract}
89
90\section{Introduction}
91
[895]92Although the finite state machine methods used
93in the scanning and parsing of text streams is considered to be the
94hardest of the 13 dwarves'' to parallelize \cite{Asanovic:EECS-2006-183},
95parallel bitstream technology shows considerable promise for these
[900]96%types of applications\cite{PPoPP08,CameronHerdyLin2008,Green2009}.
[1185]97types of applications \cite{PPoPP08,CameronHerdyLin2008}.
[895]98In this approach, character streams are processed $N$ positions at
99a time using the $N$-bit SIMD registers commonly found on commodity
100processors (e.g., 128-bit XMM registers on Intel/AMD chips).
101This is achieved by first slicing the byte streams into eight separate
102basis bitstreams, one for each bit position within the byte.
103These basis bitstreams are then combined with bitwise logic and
104shifting operations to compute further parallel bit streams of
105interest, such as the \verb:[<]: bit stream marking the position
106of all opening angle brackets in an XML document.
[879]107
[895]108Using these techniques as well as the {\em bit scan}
109instructions also available on commodity processors, the
110Parabix 1 XML parser was shown to considerably accelerate XML
[900]111% parsing in comparison with conventional byte-at-a-time parser
112parsing in comparison with conventional byte-at-a-time parsers
[895]113in applications such as statistics gathering \cite{CameronHerdyLin2008} and
114as GML to SVG conversion \cite{Herdy2008}
[893]115Other efforts to accelerate XML parsing include the use of custom
[1185]116XML chips \cite{Leventhal2009}, FPGAs \cite{DaiNiZhu2010}, careful coding and schema-based processing\cite{XMLScreamer} and
117multithread/multicore speedups based on data parallelism\cite{Shah2009,ZhangPanChiu09}.
[879]118
119In this paper, we further increase the parallelism in our methods
120by introducing a new parallel scanning primitive using bitstream
[895]121addition.   In essence, this primitive replaces the sequential bit
122scan operations underlying Parabix 1 with a new approach that
123independently advances multiple marker bits in parallel using
124simple addition and logic operations.   This paper documents the
125technique and evaluates it in application to the problem of XML
126parsing and well-formedness checking.
[879]127
[895]128Section 2 reviews the basics of parallel bitstream technology
129and introduces our new parallel scanning primitive.  Section 3
130goes on to show how this primitive may be used in XML scanning
131and parsing, while Section 4 discusses the construction of a
132complete XML well-formedness checker based on these techniques.
133Section 5 then briefly describes the compiler technology used to
134generate the low level code for our approach.  A performance
135study in Section 6 shows that the new Parabix 2 parser is
136dramatically faster than traditional byte-at-a-time parsers
137as well as the original Parabix 1 parser, particularly for
138dense XML markup.  Section 7 concludes the paper.
139
140
[893]141% The remainder of this paper is organized as follows.
142% Section 2 reviews the basics of parallel bitstream technology
143% and introduces our new parallel scanning primitive.
144% Section 3 illustrates how this primitive may be used
145% in the lexical processing of XML references including the
146% parallel identification of errors.   Section 4 goes on
147% to consider the more complex task of XML tag processing
148% that goes beyond mere tokenization.
149% Building on these methods, Section 5 describes how to
150% construct a
151% complete solution to the problem of XML parsing and
152% well-formedness checking, in order
153% to gauge the applicability and power of the techniques.
154% Section \ref{sec:compile} then considers
155% the translation of high-level operations on unbounded bitstreams into
156% equivalent low-level code using SIMD intrinsics in the C programming
157% language.
158% Performance results are presented in section 7, comparing
159% the results of our generated implementations in comparison with
160% a number of existing alternatives.
161% The paper concludes with
162% comments on the current status of the work and directions for
163% further research.
[879]164
165\section{The Parallel Bitstream Method}\label{sec:parabit}
166
[884]167\begin{figure}[b]
[879]168\begin{center}
169\begin{tabular}{cr}\\
170source data $\vartriangleleft$ & \verb----173942---654----1----49731----321--\\
171$B_7$ & \verb.......................................\\
172$B_6$ & \verb.......................................\\
173$B_5$ & \verb111111111111111111111111111111111111111\\
174$B_4$ & \verb....111111...111....1....11111....111..\\
175$B_3$ & \verb1111...1..111...1111.1111.1...1111...11\\
176$B_2$ & \verb1111.1..1.1111111111.11111.1..1111...11\\
177$B_1$ & \verb.....11..1...1.............11.....11...\\
178$B_0$ & \verb11111111..111.1.111111111.111111111.111\\
179\verb:[0-9]: & \verb....111111...111....1....11111....111..\\
180\end{tabular}
181\end{center}
182\caption{Basis and Character-Class Bitstreams}
183\label{fig:inputstreams}
184\end{figure}
185
186\subsection{Fundamentals}
187
[883]188A bitstream is simply a sequence of $0$s and $1$s, where there is one such bit in the bitstream for each character in a source data stream.
[1302]189For parsing, and other text processing tasks, we need to consider multiple properties of characters at different stages during the parsing process.
190A bitstream can be associated with each of these properties, and hence there will be multiple (parallel) bitstreams associated with a source data stream of characters.
[879]191
192The starting point for bitstream methods are \emph{basis} bitstreams
193and their use in determining \emph{character-class} bitstreams.
[900]194The $k$th basis bitstream $B_k$ consists of the $k$th bit (0-based, starting at the the least significant bit)
[879]195of each character in the source data stream;
196thus each $B_k$ is dependent on the encoding of the source characters (ASCII, UTF-8, UTF-16, etc.).
[893]197Given these basis bitstreams, it is then possible to combine them
[879]198using bitwise logic in order to compute character-class
[893]199bitstreams, that is, streams that identify the positions at which characters belonging
[879]200to a particular class occur.  For example, the character class bitstream
201$D=$\verb:[0-9]: marks with $1$s the positions at which decimal digits
202occur.    These bitstreams are illustrated in Figure \ref{fig:inputstreams},
203for an example source data stream consisting of digits and hyphens.
204This figure also illustrates some of our conventions for figures:  the left triangle $\vartriangleleft$ after
205source data'' indicates that all streams are read from right to left
206(i.e., they are in little-endian notation).  We also use hyphens
207in the input stream represent any character that is not relevant to a character
208class under consideration, so that relevant characters stand out.
209Furthermore, the $0$ bits in the bitstreams are represented by periods,
210so that the $1$ bits stand out.
211
212
[893]213Transposition of source data to basis bitstreams and calculation
[879]214of character-class streams in this way is an overhead on parallel bit
215stream applications, in general.   However, using the SIMD
[1186]216capabilities of current commodity processors, these operations are
[879]217fast, with an amortized overhead of about 1 CPU cycle per byte for
218transposition and less than 1 CPU cycle per byte for all the character
219classes needed for XML parsing \cite{CameronHerdyLin2008}.
[895]220%Improved instruction sets using parallel extract operations or
221%inductive doubling techniques may further reduce this overhead significantly \cite{CameronLin2009,HilewitzLee2006}.
[879]222
223Beyond the bitwise logic needed for character class determination,
224we also need \emph{upshifting} to deal with sequential combination.
225The upshift $n(S)$ of a bitstream $S$ is obtained by shifting the bits in $S$ one position forward,
226then placing a $0$ bit in the starting position of the bitstream; $n$ is meant to be mnemonic of next''.
227In $n(S)$, the last bit of $S$ may be eliminated or retained for error-testing purposes.
228
229\subsection{A Parallel Scanning Primitive}
230
231In this section, we introduce the principal new feature of the paper,
232a parallel scanning method based on bitstream addition.   Key to this
233method is the concept of {\em marker} bitstreams.
234Marker bitstreams are used to represent positions of interest in the
235scanning or parsing of a source data stream.
236The appearance of a 1 at a position in a marker bitstream could, for example, denote
[883]237the starting position of an XML tag in the data stream.   In general, the set of
[879]238bit positions in a marker bitstream may be considered to be the current
239parsing positions of multiple parses taking place in parallel throughout
240the source data stream.
241
242Figure \ref{fig:scan1} illustrates the basic concept
243underlying parallel parsing with bitstream addition.
[895]244All streams are shown in little-endian
[879]245representation, with streams reading from right-to-left.
[895]246The first row shows a source data stream that includes several
247spans of digits, together with other nondigit characters shown
[879]248as hyphens.  The second row specifies the parsing problem
[895]249using a marker bitstream $M_0$ to mark four initial marker
250positions.  In three instances, these markers are at
251the beginning (i.e., little end) of a span, while one is in
252the middle of a span.
[879]253The parallel parsing task is to move each
[900]254of the four markers forward (to the left) through the corresponding spans of
[879]255digits to the immediately following positions.
256
257\begin{figure}[tbh]
258\begin{center}
[895]259\begin{tabular}{cr}\\
260source data $\vartriangleleft$ & \verb----173942---654----1----49731----321--\\
[900]261$M_0$ & \verb.........1.....1....1......1...........\\
[895]262$D =$\verb:[0-9]: & \verb....111111...111....1....11111....111..\\
263$M_0 + D$ & \verb...1........1......1....1...11....111..\\
264$M_1 = (M_0 + D) \wedge \neg D$ & \verb...1........1......1....1..............
[879]265\end{tabular}
[895]266
267
[879]268\end{center}
[879]270\label{fig:scan1}
271\end{figure}
272
273The third row of Figure \ref{fig:scan1}
274shows the derived character-class bitstream $D$ identifying
275positions of all digits in the source stream.
276The fourth row then illustrates the key concept: marker movement
277is achieved by binary addition of the marker and character
278class bitstreams.  As a marker 1 bit is combined using binary addition to
279a span of 1s, each 1 in the span becomes 0, generating
[895]280a carry to add to the next position to the left.
281For each such span, the process terminates at the left end
[879]282of the span, generating a 1 bit in the immediately
[895]283following position.   These generated 1 bits represent
284the moved marker bits.   However, the result of the
286not involved in the scan operation.
[1186]287These are easily removed as shown in the fifth row,
[895]288by applying bitwise logic to mask
[879]289off any bits from the digit bitstream; these can never
290be marker positions resulting from a scan.
292the regular expression \verb:[0-9]*: for any reasonable
293(conflict-free) set of initial markers specified in $M_0$.
[879]294
295
297% the regular expression \verb:[0-9]*: for any reasonable
298% (conflict-free) set of initial markers specified in $M_0$.
299% A conflict occurs when a span from one marker would run
300% into another marker position.   However, such conflicts
301% do not occur with the normal methods of marker bitstream
302% formation, in which unique syntactic features of
303% the input stream are used to specify the initial marker
304% positions.
[879]305
306In the remainder of this paper, the notation $s(M, C)$
307denotes the operation to scan
308from an initial set of marker positions $M$ through
309the spans of characters belonging to a character class $C$ found at each position.
[1185]310$s(M, C) = (M + C) \wedge \neg C$
[879]311
312
[888]313\section{XML Scanning and Parsing}
[879]314\label{sec:errorstream}
315
[888]316We now consider how the parallel scanning primitive can
317be applied to the following problems in scanning and
318parsing of XML structures:  (1) parallel scanning of XML decimal character references,
319and (2) parallel parsing of XML start tags.
320The grammar of these structures is shown in Figure \ref{fig:xmlgrmr}.
[879]321
322\begin{figure}[tbh]
323\begin{center}
324\begin{tabular}{rcl}
[1185]325DecRef & ::=   &        '\verb:&#:' Digit${}^{+}$ '\verb:;:'  \\
[888]326Digit  & ::=   &         \verb:[0-9]:\\
[1185]327STag         &  ::=   &        '\verb:<:' Name (W  Attribute)* W${}^{?}$ '\verb:>:'  \\
328Attribute & ::=   &        Name W${}^{?}$ '=' W${}^{?}$ AttValue \\
329AttValue  &           ::=   &      (  \verb:":' \verb:[^<"]*: \verb:":') $|$ (\verb:':'' \verb:[^<']*: \verb:':'') \\
330        W       &    ::=   &    (\verb:\x20: $|$ \verb:\x9: $|$ \verb:\xD: $|$ \verb:\xA:)${}^{+}$ \\
[888]331%DQuoted & ::= & \verb:[^<"]*:  \\
332%SQuoted & ::= & \verb:[^<']*:
[879]333\end{tabular}
334\end{center}
[888]335\caption{XML Grammar: Decimal Character References and Start Tags}
336\label{fig:xmlgrmr}
[879]337\end{figure}
338
[888]339\begin{figure}[b]
340\begin{center}
341\begin{tabular}{l@{}lr}\\
342\multicolumn{2}{l}{source data $\vartriangleright$}
343                                         & \verb-&#978;-&9;--&#;--&#13!-\\
344$M_0$ &                                  & \verb.1......1....1....1.....\\
345$M_1$ & $= n(M_0)$                      & \verb..1......1....1....1....\\
346$E_0$ & $= M_1 \wedge \neg$\verb:[#]:  & \verb.........1..............\\
347$M_2$ & $= n(M_1 \wedge \neg E_0)$     & \verb...1...........1....1...\\
348$E_1$ & $= M_2 \wedge \neg D$          & \verb...............1........\\
349$M_3$ & $= s(M_2 \wedge \neg E_1, D)$  & \verb......1...............1.\\
350$E_2$ & $= M_3 \wedge \neg$\verb:[;]: & \verb......................1.\\
351$M_4$ & $= M_3 \wedge \neg E_2$        & \verb......1.................\\
352$E$  & $= E_0 \, | \, E_1 \, | \, E_2$  & \verb.........1.....1......1.
353\end{tabular}
354\end{center}
355\caption{Parsing Decimal References}
356\label{fig:decref}
357\end{figure}
358
[879]359Figure \ref{fig:decref} shows the parallel parsing of
[901]360decimal references together with error checking.
361For clarity, the streams are now shown in left-to-right
362order as indicated by the $\vartriangleright$ symbol.
[879]363The source data includes four instances of potential
364decimal references beginning with the \verb:&: character.
365Of these, only the first one is legal according to
366the decimal reference syntax, the other three instances
367are in error.   These references may be parsed in
368parallel as follows.  The
369starting marker bitstream $M_0$ is formed from the \verb:[&]:
370character-class bitstream as shown in the second row.  The next row shows the
371result of the marker advance operation $n(M_0)$ to
372produce the new marker bitstream $M_1$.  At this point,
[1186]373the grammar requires a hash mark, so the first error bitstream $E_0$ is
[879]374formed using a bitwise and'' operation combined with negation,
375to indicate violations of this condition.
376Marker bitstream $M_2$ is then defined as those positions
377immediately following any $M_1$ positions not in error.
378In the following row, the condition that at least
379one digit is required is checked to produce error bitstream $E_1$.
380A parallel scan operation is then applied through the
381digit sequences as shown in the next row to produce
382marker bitstream $M_3$.  The final error bitstream $E_2$ is
383produced to identify any references without a
384closing semicolon.
385In the penultimate row, the final marker bitstream $M_4$ marks the
386positions of all fully-checked decimal references, while the
387last row defines a unified error bitstream $E$
388indicating the positions of all detected errors.
389
[901]390Initialization of marker streams may be achieved in various ways,
391dependent on the task at hand.
[879]392In the XML parsing context,
393we rely on an important property of well-formed
394XML: after an initial filtering pass to identify
395XML comments, processing instructions and CDATA
396sections, every remaining \verb:<: in the
397file must be the initial character of a start,
398end or empty element tag, and every remaining \verb:&:
399must be the initial character of a general entity
[888]400or character reference. These assumptions permit easy creation of
401marker bitstreams for XML tags and XML references.
[879]402
[888]403The parsing of XML start tags is a richer problem, involving
404sequential structure of attribute-value pairs as shown in Figure \ref{fig:xmlgrmr}.
405Using the bitstream addition technique, our method
[879]406is to start with the opening angle bracket of all tags as
407the initial marker bitstream for parsing the tags in parallel,
408advance through the element name and then use an iterative
409process to move through attribute-value pairs.
410
411Figure \ref{fig:stag-ex}
[884]412illustrates the parallel parsing of three XML start tags.
[879]413The figure omits determination
414of error bitstreams, processing of single-quoted attribute values and handling
[883]415of empty element tags, for simplicity.  In this figure, the first
[879]416four rows show the source data and three character class bitstreams:
417$N$ for characters permitted in XML names,
418$W$ for whitespace characters,
419and $Q$ for characters permitted within a double-quoted attribute value string.
420
421\begin{figure*}[tbh]
422\begin{center}\footnotesize
423
[884]424\begin{tabular}{lr}\\
425source data $\vartriangleright$ & \verb--<e a= "137">---<el2 a="17" a2="3379">---<x>--\\
426$N =$ name chars & \verb11.1.1...111..111.111.1..11..11..1111..111.1.11\\
427$W =$ white space & \verb....1..1.............1......1..................\\
[1185]428$Q = \neg$\verb:["<]: & \verb11.11111.111.1111.111111.11.1111.1111.1111.1111\\
[879]429\\
[884]430$M_0$ & \verb..1..............1........................1....\\
431$M_1 = n(M_0)$ & \verb...1..............1........................1...\\
432$M_{0,7} = s(M_1, N)$ & \verb....1................1......................1..\\
433$M_{0,8} = s(M_{0,7}, W) \wedge \neg$\verb:[>]: & \verb.....1................1........................\\
[879]434\\
[1185]435$M_{1,1} = s(M_{0,8}, N)$ & \verb......1................1.......................\\
[884]436$M_{1,2} = s(M_{1,1}, W) \wedge$\verb:[=]: & \verb......1................1.......................\\
437$M_{1,3} = n(M_{1,2})$ & \verb.......1................1......................\\
[1185]438$M_{1,4} = s(M_{1,3}, W) \wedge$\verb:["]: & \verb........1...............1......................\\
[884]439$M_{1,5} = n(M_{1,4})$ & \verb.........1...............1.....................\\
440$M_{1,6} = s(M_{1,5}, Q) \wedge$\verb:["]: & \verb............1..............1...................\\
441$M_{1,7} = n(M_{1,6})$ & \verb.............1..............1..................\\
442$M_{1,8} = s(M_{1,7}, W) \wedge \neg$\verb:[>]: & \verb.............................1.................\\
[879]443\\
[884]444$M_{2,1} = s(M_{1,8}, N)$ & \verb...............................1...............\\
445$M_{2,2} = s(M_{2,1}, W) \wedge$\verb:[=]: & \verb...............................1...............\\
446$M_{2,3} = n(M_{2,2})$ & \verb................................1..............\\
447$M_{2,4} = s(M_{2,3}, W) \wedge$\verb:["]: & \verb................................1..............\\
448$M_{2,5} = n(M_{2,4})$ & \verb.................................1.............\\
449$M_{2,6} = s(M_{2,5}, Q) \wedge$\verb:["]: & \verb.....................................1.........\\
450$M_{2,7} = n(M_{2,6})$ & \verb......................................1........\\
451$M_{2,8} = s(M_{2,7}, W) \wedge \neg$\verb:[>]: & \verb...............................................
[879]452\end{tabular}
453\end{center}
454\caption{Start Tag Parsing}
455\label{fig:stag-ex}
456\end{figure*}
457
458
[888]459The parsing process is illustrated in the remaining rows of the
[879]460figure.    Each successive row shows the set of parsing markers as they
462Overall, the sets of marker transitions can be divided into three groups.
463
464The first group
465$M_0$ through $M_{0,8}$ shows the initiation of parsing for each of the
[884]466 tags through the
[879]467opening angle brackets and  the element names, up to the first
[1185]468attribute name, if present.  Note that there are no attribute names
[884]469in the final tag shown, so the corresponding marker becomes zeroed
[879]470out at the closing angle bracket.
471Since $M_{0,8}$ is not all $0$s, the parsing continues.
472
473The second group of marker transitions
474$M_{1,1}$ through $M_{1,8}$ deal with the parallel parsing of the first attribute-value
[884]475pair of the remaining tags.
[879]476After these operations, there are no more attributes
[884]477in the first tag, so its corresponding marker becomes zeroed out.
[900]478However, $M_{1, 8}$ is not all $0$s, as the second tag still has an unparsed attribute-value pair.
[879]479Thus, the parsing continues.
480
481The third group of marker transitions $M_{2,1}$ through $M_{2,8}$ deal with the parsing of
[884]482the second attribute-value pair of this tag.  The
[879]483final transition to $M_{2,8}$ shows the zeroing out of all remaining markers
484once two iterations of attribute-value processing have taken place.
485Since $M_{2,8}$ is all $0$s, start tag parsing stops.
486
487The implementation of start tag processing uses a while loop that
488terminates when the set of active markers becomes zero,
489i.e.\  when some $M_{k, 8} = 0$.
490Considered
491as an iteration over unbounded bitstreams, all start tags in the document
492are processed in parallel, using a number of iterations equal to the maximum
493number of attribute-value pairs in any one tag in the document.
[884]494However, in block-by-block processing, the cost of iteration is considerably reduced; the iteration for
[879]495each block only requires as many steps as there are attribute-value pairs
496overlapping the block.
497
498
499
500
501%\subsection{Name Scans}
502%To illustrate the scanning of the name found in an XML start tag,
503%let us consider a sequence that might be found in an HTML file,
504%\verb:<div id="myid">:,
505%which is shown as the source data stream in Figure \ref{fig:stag-scan}.
506
507%\begin{figure}[tbh]
508%\begin{center}
509%\begin{tabular}{cr}\\
510%source data & \verb:<div id="myid">:\\
511%$M_0$ & \verb1..............\\
512%$C_0$ & \verb.111.11...1111.\\
513%$M_1 = n(M_0)$ & \verb.1.............\\
514%$M_2 = s(M_1, D_0) \wedge \neg C_0$ & \verb....1.........\\
515%lastline & \verb...............
516%\end{tabular}
517%\end{center}
518%\caption{Scanning Names}
519%\label{fig:stag-scan}
520%\end{figure}
521
522%If we set our initial marker bitstream according to the procedure outlined in our discussion of marker bitstream initialization, we %obtain the bitstream $M_0$.
523%According to the grammar in Figure \ref{fig:stag-grmr}, we can then look for a \verb:Name: in an \verb:STag: after we have found a %5\verb:<:.
524%So, $M_1$ is the marker bitstream for the starting position of our name.
525%Although we do not know the length of the name, the $C_0$ bit vector can easily be set to $1$ for the characters that can be contained %in a name.
526%We can then use the scan function in a manner similar to how it was used in Figure \ref{fig:scan2} to scan through the entire name to %identify its end position.
527
[888]528Following the pattern shown here, the remaining syntactic
529features of XML markup can similarly be parsed with
[1186]530bitstream based methods.   One complication is that the
532CDATA sections and processing instructions must be
533performed first to determine those regions of text
534within which ordinary XML markups are not parsed (i.e.,
535within each of these types of construct.   This is handled
[1186]536by first parsing these structures and
[888]537then forming a {\em mask bitstream}, that is, a stream that
538identifies spans of text to be excluded from parsing
539(comment and CDATA interiors, parameter text to processing instructions).
[879]540
541
542\section{XML Well-Formedness}
543
544In this section, we consider the full application of the parsing techniques
[883]545of the previous section to the problem of XML well-formedness checking \cite{TR:XML}.
[893]546% This application is useful as a well-defined and commercially significant
547% example to assess the overall applicability of parallel bitstream techniques.
548% To what extent can the well-formedness requirements of XML be
549% completely discharged using parallel bitstream techniques?
550% Are those techniques worthwhile in every instance, or
551% do better alternatives exist for certain requirements?
552% For those requirements that cannot be fully implemented
553% using parallel bitstream technology alone, what
554% preprocessing support can be offered by parallel bitstream
555% technology to the discharge of these requirements in other ways?
556% We address each of these questions in this section,
557% and look not only at the question of well-formedness, but also at
558We look not only at the question of well-formedness, but also at
[879]559the identification of error positions in documents that
560are not well-formed.
561
562
[888]563%\subsection{Error and Error-Check Bitstreams}
[879]564
565Most of the requirements of XML well-formedness checking
566can be implemented using two particular types of computed
[883]567bitstream: {\em error bitstreams}, introduced in the previous section, and {\em error-check bitstreams}.
568Recall that an error bitstream stream is a stream marking the location of definite errors in accordance with
569a particular requirement.  For example, the
[879]570$E_0$, $E_1$, and $E_2$ bitstreams as computed during parsing of
571decimal character references in Figure \ref{fig:decref}
[883]572are error bitstreams.  One bits mark definite errors and zero bits mark the
[893]573absence of an error.
574% absence of error according to the requirement.
[883]575Thus the complete absence of errors according to the
576requirements listed may be determined by forming the
577bitwise logical or'' of these bitstreams and confirming
578that the resulting value is zero. An error check bitstream is one
[879]579that marks potential errors to be further checked in
580some fashion during post-bitstream processing.
581An example is the bitstream marking the start positions
582of CDATA sections.   This is a useful information stream
583computed during bitstream processing to identify opening
584\verb:<![: sequences, but also marks positions to
585subsequently check for the complete opening
[883]586delimiter  \verb:<![CDATA[: at each position.
[879]587
[883]588In typical documents, most of these error-check streams will be quite sparse
[893]589% or even zero.   Many of the error conditions could
590or even zero.   Many error conditions could
[879]591actually be fully implemented using bitstream techniques,
[883]592but at the cost of a number of additional logical and shift
[893]593operations.   In general, the conditions are
[879]594easier and more efficient to check one-at-a-time using
595multibyte comparisons on the original source data stream.
596With very sparse streams, it is very unlikely that
597multiple instances occur within any given block, thus
598eliminating the benefit of parallel evaluation of the logic.
599
600The requirement for name checking merits comment.   XML
601names may use a wide range of Unicode character values.
602It is too expensive to check every instance of an XML name
603against the full range of possible values.   However, it is
[1186]604possible and inexpensive to use parallel bitstream
[879]605techniques to verify that any ASCII characters within a name
606are indeed legal name start characters or name characters.
607Furthermore, the characters that may legally follow a
608name in XML are confined to the ASCII range.  This makes
609it useful to define a name scan character class to include all the legal ASCII characters
610for names as well as all non-ASCII characters.
[1186]611A namecheck character class bitstream will then be defined to identify non-ASCII
[879]612characters found within namescans.   In most documents
613this bitstream will be all $0$s; even in documents with substantial
614internationalized content, the tag and attribute names used
615to define the document schema tend to be confined to the
616ASCII repertoire.   In the case that this bitstream is nonempty,
617the positions of all 1 bits in this bitstream denote characters
618that need to be individually validated.
619
620Attribute names within a single XML start tag or empty
[883]621element tag must be unique.  This requirement could be
622implemented using one of several different approaches. Standard
623approaches include: sequential search, symbol lookup, and Bloom filters
624\cite{DaiNiZhu2010}.
[879]625
[893]626% In general, the use of error-check bitstreams is a straightforward,
627% convenient and reasonably efficient mechanism for
628% checking the well-formedness requirements.
[879]629
[888]630%\subsection{Tag Matching}
[879]631
632Except for empty element tags, XML tags come in pairs with
633names that must be matched.   To discharge this requirement,
634we form a bitstream consisting of the disjunction of three
635bitstreams formed during parsing: the bitstream marking the
636positions of start or empty tags (which have a common
637initial structure), the bitstream marking tags that end using
638the empty tag syntax (\verb:/>:''), and the bitstream
639marking the occurrences of end tags.   In post-bitstream
640processing, we iterate through this computed bitstream
[883]641and match tags using an iterative stack-based approach.
[879]642
[888]643%\subsection{Document Structure}
[879]644
[1185]645An XML document consists of a single root element within
646which all others contained; this constraint is also
647checked during post-bitstream processing.   In addition,
648we define the necessary "miscellaneous" bitstreams
649for checking the prolog and epilog material before
650and after the root element.
[879]651
[888]652%\subsection{Summary}
[879]653
[900]654Overall, parallel bitstream techniques are well-suited to
[879]655verification problems such as XML well-formedness checking.
656Many of the character validation and syntax checking requirements
657can be conveniently and efficiently implemented using error streams.
658Other requirements are also supported by the computation of
659error-check streams for simple post-bitstream processing or
660composite stream over which iterative stack-based procedures
[901]661can be defined for checking recursive syntax.  To assess
662the completness of our analysis, we have confirmed that
663our implementations correctly handle all the well-formedness
664checks of the W3C XML Conformance Test Suite.
[879]665
666\section{Compilation to Block-Based Processing}
667\label{sec:compile}
[901]668While our Python implementation of the techniques described in the previous section works on unbounded bitstreams, a corresponding
[879]669C implementation needs to process an input stream in blocks of size equal to the
670SIMD register width of the processor it runs on.
[894]671So, to convert Python code into C, the key question becomes how
[893]672to transfer information from one block to the next.
[894]673
674The answer lies in the use of {\em carry bits}.
675The parallel scanning primitive uses only addition and bitwise logic.
676The logic operations do not require information flow
677accross block boundaries, so the information flow is entirely
678accounted by the carry bits for addition.   Carry bits also
[879]679capture the information flow associated with upshift
680operations, which move information forward one position
681in the file.   In essence, an upshift by one position for
682a bitstream is equivalent to the addition of the stream
683to itself; the bit shifted out in an upshift is in this
684case equivalent to the carry generated by the additon.
685
686Properly determining, initializing and inserting carry bits
[893]687into a block-by-block implementation of parallel bitstream
[879]688code is a task too tedious for manual implementation.
689We have thus developed compiler technology to automatically
690insert declarations, initializations and carry save/restore
691operations into appropriate locations when translating
[893]692Python operations on unbounded bitstreams into the
[879]693equivalent low-level C code implemented on a block-by-block
694bases.  Our current compiler toolkit is capable of inserting
695carry logic using a variety of strategies, including both
696simulated carry bit processing with SIMD registers, as
697well as carry-flag processing using the processor general
698purpose registers and ALU.   Details are beyond the
699scope of this paper, but are described in the on-line
700source code repository at parabix.costar.sfu.ca.
701
[894]702
[879]703\section{Performance Results}
704
705In this section, we compare the performance of our \verb:xmlwf:
[900]706implementation using the Parabix 2 technology described above with several
[879]707other implementations.
708These include the original \verb:xmlwf:
709distributed as an example application of the \verb:expat: XML
710parser,  implementations based on the widely used Xerces
711open source parser using both SAX and DOM interfaces,
712and an implementation using our prior Parabix 1 technology with
713bit scan operations.
714
715Table \ref{XMLDocChars}
716shows the document characteristics of the XML instances selected for this performance study,
717including both document-oriented and data-oriented XML files.
[883]718The jawiki.xml and dewiki.xml XML files are document-oriented XML instances of Wikimedia books, written in Japanese and German, respectively. The remaining files are data-oriented.  The roads.gml file is an instance of Geography Markup Language (GML),
[895]719a modeling language for geographic information systems as well as an open interchange format for geographic transactions on the Internet.  The po.xml file is an example of purchase order data, while the soap.xml file contains a large SOAP message.
[879]720Markup density is defined as the ratio of the total markup contained within an XML file to the total XML document size.
721This metric is reported for each document.
722
723\begin{table*}[tbh]
724\begin{center}
[883]725\begin{tabular}{|c||r|r|r|r|r|}
[879]726\hline
727File Name               & dewiki.xml            & jawiki.xml            & roads.gml     & po.xml        & soap.xml \\ \hline
728File Type               & document      & document      & data  & data  & data   \\ \hline
729File Size (kB)          & 66240                 & 7343                  & 11584         & 76450         & 2717 \\ \hline
730Markup Item Count       & 406792                & 74882                 & 280724        & 4634110       & 18004 \\ \hline
731Attribute Count         & 18808                 & 3529                  & 160416        & 463397        & 30001\\ \hline
732Avg. Attribute Size     & 8                     & 8                     & 6             & 5             & 9\\ \hline
733Markup Density          & 0.07                  & 0.13                  & 0.57          & 0.76          & 0.87  \\ \hline
734
735\end{tabular}
736\end{center}
737 \caption{XML Document Characteristics}
738 \label{XMLDocChars}
739\end{table*}
740
741Table \ref{parsers-cpb} shows performance measurements for the
742various \verb:xmlwf: implementations applied to the
743test suite.   Measurements are made on a single core of an
[885]744Intel Core 2 system running a stock 64-bit Ubuntu 10.10 operating system,
745with all applications compiled with llvm-gcc 4.4.5 optimization level 3.
[879]746Measurements are reported in CPU cycles per input byte of
747the XML data files in each case.
748The first row shows the performance of the Xerces C parser
749using the tree-building DOM interface.
750Note that the performance
751varies considerably depending on markup density.  Note also that
752the DOM tree construction overhead is substantial and unnecessary
753for XML well-formedness checking.  Using the event-based SAX interface
754to Xerces gives much better results as shown in the
755second row.
756The third row shows the best performance of our byte-at-a-time
[885]757parsers, using the original  \verb:xmlwf: based on expat.
[879]758
759The remaining rows of Table \ref{parsers-cpb} show performance
[1185]760of parallel bitstream implementations, including post-bitstream
761processing.  The first row shows
[879]762the performance of our Parabix 1 implementation using
763bit scan instructions.   While showing a substantial speed-up
764over the byte-at-a-time parsers in every case, note also that
765the performance advantage increases with increasing markup
[1185]766density, as expected.   The last two rows show Parabix 2
767implementations using different carry-handling
768strategies, with the simd'' row referring to carry
[879]769computations performed with simulated calculation of
770propagated and generated carries using SIMD operations, while the
[1185]771adc64'' row referring to an implementation directly employing
[879]772the processor carry flags and add-with-carry instructions on
77364-bit general registers.  In both cases, the overall
[1186]774performance is impressive, with the increased
[879]775parallelism of parallel bit scans clearly paying off in
776improved performance for dense markup.
777
778
779\begin{table}[thb]
780\begin{center}
781\begin{tabular}{|c|c||c|c|c|c|c|}
782\hline
[883]783Parser Class & Parser & dewiki.xml  & jawiki.xml    & roads.gml  & po.xml & soap.xml  \\ \hline
[885]784
[898]785Byte & Xerces (DOM)    &    37.921   &    40.559   &    72.78   &    105.497   &    125.929  \\ \cline{2-7}
786at-a & Xerces (SAX)   &     19.829   &    24.883   &    33.435   &    46.891   &    57.119      \\ \cline{2-7}
787Time & expat      &  12.639   &    16.535   &    32.717   &    42.982   &    51.468      \\ \hline
788Parallel & Parabix1   &    8.313   &    9.335   &     13.345   &    16.136   &      19.047 \\ \cline{2-7}
789Bit& Parabix2 (simd)   &        6.103   &    6.445   &    8.034   &    8.685   &    9.53 \\ \cline{2-7}
790Stream & Parabix2 (adc64)       &       5.123   &    5.996   &    6.852   &    7.648   &    8.275 \\ \hline
[879]791 \end{tabular}
792\end{center}
793 \caption{Parser Performance (Cycles Per Byte)}
794\label{parsers-cpb}
795\end{table}
796
797%gcc (simd\_add)    &   6.174   &       6.405   &       7.948   &       8.565   &       9.172 \\ \hline
798%llvm (simd\_add)   &   6.104   &       6.335   &       8.332   &       8.849   &       9.811 \\ \hline
799%gcc (adc64)        &   9.23   &        9.921   &       10.394   &      10.705   &      11.751 \\ \hline
800%llvm (adc64)       &   5.757   &       6.142   &       6.763   &       7.424   &       7.952 \\ \hline
801%gcc (SAHFLAHF)    &    7.951   &       8.539   &       9.984   &       10.219   &      11.388 \\ \hline
802%llvm(SAHFLAHF)    &    5.61   &        6.02   &        6.901   &       7.597   &       8.183 \\ \hline
803
804
805
806
807\section{Conclusion}
808
809In application to the problem of XML parsing and well-formedness
810checking, the method of parallel parsing with bitstream addition
811is effective and efficient.   Using only bitstream addition
812and bitwise logic, it is possible to handle all of the
813character validation, lexical recognition and parsing problems
814except for the recursive aspects of start and end tag matching.
815Error checking is elegantly supported through the use of error
816streams that eliminate separate if-statements to check for
817errors with each byte.   The techniques are generally very
818efficient particularly when markup density is high.   However, for some
819conditions that occur rarely and/or require complex combinations
820of upshifting and logic, it may be better to define simpler
821error-check streams that require limited postprocessing using
822byte matching techniques.
823
824The techniques have been implemented and assessed for present-day commodity processors employing current SIMD technology.
825As processor advances see improved instruction sets and increases
826in width of SIMD registers, the relative advantages of the
828parsing methods is likely to increase substantially.
829Of particular benefit to this method, instruction set modifications
830that provide for more convenient carry propagation for long
831bitstream arithmetic would be most welcome.
832
833A significant challenge to the application of these techniques
834is the difficulty of programming.   The method of prototyping
835on unbounded bitstreams has proven to be of significant value
836in our work.   Using the prototyping language as input to
837a bitstream compiler has also proven effective in generating
838high-performance code.   Nevertheless, direct programming
839with bitstreams is still a specialized skill; our future
840research includes developing yet higher level tools to
841generate efficient bitstream implementations from grammars,
842regular expressions and other text processing formalisms.
843
844
[1186]845%\bibliographystyle{plain}
[1185]846
[1186]847%\bibliography{xmlperf}
[879]848
[1186]849\begin{thebibliography}{10}
[879]850
[1186]851\bibitem{Asanovic:EECS-2006-183}
852Krste Asanovic, Ras Bodik, Bryan~Christopher Catanzaro, Joseph~James Gebis,
853  Parry Husbands, Kurt Keutzer, David~A. Patterson, William~Lester Plishker,
854  John Shalf, Samuel~Webb Williams, and Katherine~A. Yelick.
855\newblock The landscape of parallel computing research: A view from {Berkeley}.
856\newblock Technical Report UCB/EECS-2006-183, EECS Department, University of
857  California, Berkeley, Dec 2006.
858
859\bibitem{TR:XML}
860Tim Bray, Jean Paoli, C.~M. Sperberg-McQueen, Eve Maler, and FranÃ§ois Yergeau.
861\newblock Extensible markup language ({XML}) 1.0 (fifth edition).
862\newblock W3C Recommendation, 2008.
863
864\bibitem{PPoPP08}
865Robert~D. Cameron.
866\newblock {A Case Study in SIMD Text Processing with Parallel Bit Streams}.
867\newblock In {\em {ACM Symposium on Principles and Practice of Parallel
868  Programming (PPoPP)}}, {Salt Lake City, Utah}, 2008.
869
870\bibitem{CameronHerdyLin2008}
871Robert~D. Cameron, Kenneth~S. Herdy, and Dan Lin.
872\newblock High performance {XML} parsing using parallel bit stream technology.
873\newblock In {\em {CASCON} '08: Proceedings of the 2008 conference of the
874  center for advanced studies on collaborative research}, pages 222--235, New
875  York, NY, USA, 2008. ACM.
876
877\bibitem{DaiNiZhu2010}
878Zefu Dai, Nick Ni, and Jianwen Zhu.
879\newblock A 1 cycle-per-byte {XML} parsing accelerator.
880\newblock In {\em FPGA '10: Proceedings of the 18th Annual ACM/SIGDA
881  International Symposium on Field Programmable Gate Arrays}, pages 199--208,
882  New York, NY, USA, 2010. ACM.
883
884\bibitem{Herdy2008}
885Kenneth~S. Herdy, David~S. Burggraf, and Robert~D. Cameron.
886\newblock High performance {GML} to {SVG} transformation for the visual
887  presentation of geographic data in web-based mapping systems.
888\newblock In {\em Proceedings of {SVG} Open 2008}, August 2008.
889
890\bibitem{XMLScreamer}
891M.~G. Kostoulas, M.~Matsa, N.~Mendelsohn, E.~Perkins, A.~Heifets, and
892  M.~Mercaldi.
893\newblock {{XML} Screamer: An Integrated Approach to High Performance {XML}
894  Parsing, Validation and Deserialization}.
895\newblock In {\em Proceedings of the 15th International Conference on World
896  Wide Web (WWW '06)}, pages 93--102, 2006.
897
898\bibitem{Leventhal2009}
899Michael Leventhal and Eric Lemoine.
900\newblock The {XML} chip at 6 years.
901\newblock In {\em International Symposium on Processing {XML} Efficiently:
902  Overcoming Limits on Space, Time, or Bandwidth}, August 2009.
903
904\bibitem{Shah2009}
905Bhavik Shah, Praveen Rao, Bongki Moon, and Mohan Rajagopalan.
906\newblock A data parallel algorithm for {XML DOM} parsing.
907\newblock In Zohra BellahsÃšne, Ela Hunt, Michael Rys, and Rainer Unland,
908  editors, {\em Database and {XML} Technologies}, volume 5679 of {\em Lecture
909  Notes in Computer Science}, pages 75--90. Springer Berlin / Heidelberg, 2009.
910
911\bibitem{ZhangPanChiu09}
912Ying Zhang, Yinfei Pan, and Kenneth Chiu.
913\newblock Speculative p-{DFA}s for parallel {XML} parsing.
914\newblock In {\em High Performance Computing (HiPC), 2009 International
915  Conference on}, pages 388--397, December 2009.
916
917\end{thebibliography}
[879]918\end{document}
919
Note: See TracBrowser for help on using the repository browser.