Post Job Free
Sign in

Process It

Location:
India
Posted:
January 26, 2013

Contact this candidate

Resume:

To Appear in the Proceedings of **th ACM/IEEE International Conference on Parallel Architectures and Compilation Techniques (PACT 2004)

Fast Paths in Concurrent Programs

Wen Xu Sanjeev Kumar Kai Li

Department of Computer Science Intel Labs Department of Computer Science

Princeton University Intel Corporation Princeton University

***@**.*********.*** *******.*****@*****.*** **@**.*********.***

ABSTRACT

Compiling concurrent programs to run on a sequential pro-

(b) Multiprocessor

P1 P1

(a) Uniprocessor

cessor presents a di cult tradeo between execution time

and size of generated code. On one hand, the process-based

approach to compilation generates reasonable sized code but P2 P2

P3 P3

incurs signi cant execution overhead due to concurrency.

On the other hand, the automata-based approach incurs a P4 P5 P4 P5

much smaller execution overhead but can result in code that

is several orders of magnitude larger.

This paper proposes a way of combining the two approaches

so that the performance of the automata-based approach can

Figure 1: Concurrent Program

be achieved without su ering the code size increase due to

it. The key insight is that the best of the two approaches

can be achieved by using symbolic execution (similar to the

proach (Section 4). The two approaches di er radically in

automata-based approach) to generate code for the com-

the concurrency overhead and the size of the generated code.

monly executed paths (referred to as fast paths) and using

A study [15] evaluated the two approaches on a set of con-

the process-based approach to generate code for the rest of

current programs written in Esterel [6]. The study found

the program. We demonstrate the e ectiveness of this ap-

that the automata-based approach resulted in code that was

proach by implementing our techniques in the ESP compiler

twice as fast as the process-based approach. However, the

and applying them to a set of lter programs and to VMMC

size of the code generated by the automata-based approach

network rmware.

was 2 3 orders of magnitude larger than that produced by

the process-based approach.

1. INTRODUCTION This paper proposes a technique for extracting and op-

Concurrency is a convenient way of structuring timizing fast paths from concurrent programs so that the

programs [19, 24] in a variety of domains including embed- performance bene t of the automata-based approach can

ded devices [6, 17], user interfaces [10, 31], programmable be achieved without signi cantly increasing the size of the

devices [21], servers [32], media-processing applications [20], generated code. A fast path is a commonly executed path

and network software stack [4, 29]. This is often true even in a program. Substantial performance improvements can

when these programs are written to run on a single proces- be achieved by aggressively optimizing the fast paths in the

sor. This is because programs in these domains are required programs. Past research [30, 26, 23] has focused on fast

to simultaneously process multiple external events at the paths in sequential programs.

same time. Concurrent programs have multiple threads of In the absence of automatic fast path extraction, fast

control that coordinate with each other to perform a single paths are often implemented manually by the programmer [21].

task. The multiple threads of control provide a convenient The programmer can insert a predicate in the program to

way of keeping track of multiple contexts in the program. check for the common case and transfer control to the fast

Figure 1 shows a concurrent program with 5 concurrent path code. The fast path code has to be functionally equiv-

threads of control (P1-P5). On a uniprocessor, the entire alent to the corresponding path in the program. The pro-

concurrent program needs to be compiled to run e ciently grammer is responsible for manually extracting and optimiz-

on a single processor. On a multiprocessor (with 2 proces- ing the fast path code.

sors), the program is partitioned so that P1-P3 are run on Although, manually extracting fast paths often results in

the rst processor while the remaining program is run on good performance, it su ers from three drawbacks. First,

the second processor. In each case, several threads of con- manually extracting fast paths involves substantial program-

trol have to be compiled to e ciently run on a sequential mer e ort. Second, manually implementing fast paths is

processor. This paper addresses this problem. very error prone. Fast paths violate abstraction boundaries

The overhead of implementing concurrency on sequen- and rely on global information like the state of the di erent

tial processors can be substantial. There are two main ap- threads of control and their local data structures. As the

proaches to compiling concurrent programs on sequential program evolves, for each change made to the concurrent

processors: process-based approach and automata-based ap- program, a corresponding change has to be made to the fast

To Appear in the Proceedings of 13th ACM/IEEE International Conference on Parallel Architectures and Compilation Techniques (PACT 2004)

path. In addition, programmers often introduce subtle bugs

when they try to aggressively optimize fast paths. Third,

it is di cult to build robust fast paths. One often ends

up with fast paths that help simple applications with very

predictable process interactions but have little impact on ap-

channel hostSendRequestC( int, int ) external out;

1:

plications. The more speci c the fast path predicate (that channel hostFetchRequestC( int ) external out;

2:

identi es the fast path), the more specialized and e cient channel translateRequestC( int, int );

3:

fast path will be. However, it also means that the predicate channel translateReplyC( int, int );

4:

will be satis ed less often. It is easier to experiment with channel dataSendC( int, int );

5:

channel networkSendC( int ) external in;

6:

various fast paths and identify the right one to employ if the

7:

programmer e ort needed to build a fast path is small.

process hostRequest {

8:

var virtualAddress, physicalAddress, size, source;

9:

Summary of Contributions. This paper presents tech- while (true) {

10:

niques to automatically generate fast paths in concurrent alt {

11:

in( hostSendRequestC, virtualAddress, size) {

12:

programs using a compiler. This approach avoids the draw-

out( translateRequestC, virtualAddress, size);

13:

backs associated with manual fast path extraction while pro-

while ( true) {

14:

viding the performance bene ts. The main contributions of in( translateReplyC, physicalAddress, size);

15:

this paper are the following: if ( size == 0)

16: break;

out( dataSendC, physicalAddress, size);

17:

1. It extends the traditional de nition of fast paths to

} // while

18:

make them more exible (Section 2.2).

19: #1

2. It proposes a variant of path expressions that not only } // in

20:

allows the programmer to specify fast paths in concur- in( hostFetchRequestC, source) {

21:

rent programs but also lets them specify the scheduling // Code omitted

22:

choices made on the fast path. A key feature of the fast } // in

23:

} // alt

24:

path speci cations is that they are just hints while

} // while

25:

they improve the performance of the program, they do

26: }

not change the semantics of the program and, there- 27:

fore, do not a ect program correctness. (Section 3) process translateAddress {

28:

3. It presents a technique for extracting and optimizing constant pageSize = 4096;

29:

fast paths in concurrent programs. This technique var virtualAddress, physicalAddress, size;

30:

while (true) {

31:

delivers the performance of the automata-based ap-

in( translateRequestC, virtualAddress, size);

32:

proach without the associated blowup in the size of

assert( virtualAddress % pageSize == 0);

33:

the generated program. One important aspect of this assert( size % pageSize == 0);

34:

technique is that it preserves the fairness guarantees while ( size > 0) {

35:

of the program. (Section 4) if ( translationUnavailable(virtualAddress)) { #2

36:

4. It provides a practical demonstration of the approach // Code to f etch the translation entry

37:

} // if

38:

by implementing the techniques described in the con-

39: physicalAddress = translate( virtualAddress);

text of the ESP [21] compiler. A set of lter programs

out( translateReplyC, physicalAddress, pageSize);

40:

and VMMC network rmware are used to evaluate the 41: size = size - pageSize;

e ectiveness of the technique. On lter programs, our } // while

42:

technique outperforms even the automata-based ap- out( translateReplyC, 0, 0); // Done

43:

proach without any dramatic increase in the size of the } // while

44:

45: }

generated code. On VMMC rmware, our technique

46:

achieves up to 22% improvement in latency and up to

process networkSend {

47:

40% improvement in bandwidth over the process-based var physicalAddress, size, packet;

48:

approach. (Section 6) while (true) {

49:

in( dataSendC, physicalAddress, size);

50:

51: packet = preparePacket( physicalAddress, size);

2. PROBLEM STATEMENT out( networkSendC, packet); #3

52:

} // while

53:

This paper presents a technique to reduce the concurrency

54: }

overhead in concurrent programs by extracting and aggres-

sively optimizing fast path code. This section starts with a

Note: The assert statements in the code are used to state

description of a simple concurrent language and an example

the assumptions made to simplify the example. The #1 and

that is used throughout this paper. It then describes fast

#2 are annotations to mark statements and are used in

paths in detail. Finally, it discusses the scope of the paper.

Section 3.

2.1 Concurrent Programs

In this section, we describe a simple concurrent program-

Figure 2: A Running Example. (Illustrated in Figure 3)

ming language that we use to demonstrate the techniques

presented in this paper.

In this language, concurrency is expressed using processes

and channels. A program consists of a set of processes com-

municating with each other over channels. Each process

To Appear in the Proceedings of 13th ACM/IEEE International Conference on Parallel Architectures and Compilation Techniques (PACT 2004)

C2 Modular Concurrent

C1

C1

Program Fast Paths

C3

P1 P2

Common Case

P1 C2 P2

C4

C5

C3 C4

Process Abort

P3

Channel Normal Exit

P3 P4

External Channel

C6

C5 C6

Process

Figure 3: Example. Illustration of the example in Fig- Channel

ure 2. Process P1 is hostRequest, P2 is translateAddress,

and P3 is networkSend. Channel C1 is hostSendRequestC, External Channel

C2 is hostFetchRequestC, C3 is translateRequestC,

C4 is translateReplyC, C5 is dataSendC, and C6 is

networkSendC. Figure 4: Fast Paths in Concurrent Programs

represents a sequential ow of control in the concurrent pro- Figure 2 and Figure 3 show a code fragment that is used

gram. as a running example in this paper. It is extracted from

Processes communicate with each other over channels. our VMMC rmware code [21] for a gigabit network card.

Messages are sent over the channels using the out opera- The code shows the steps involved in sending a packet in

tion and received using the in operation. Communication the VMMC rmware [21]. When the user application has

over channels is synchronous1 or unbu ered a process has some data to send, it sends a request via channel host-

to be attempting to perform an out operation on a channel SendRequestC to process hostRequest. After process hostRe-

concurrently with another process attempting to perform an quest gets the request, it rst translates the virtual address

in operation on that channel before the message can be suc- to physical address, and then sends the data page by page to

cessfully transferred over the channel. Consequently, both in the destination. Process hostRequest consults process trans-

and out are blocking operations. The alt statement allows a lateAddress for address translation. Process translateAd-

process to wait on in and out operations on several di erent dress has a table which caches recently translated addresses.

channels till one of them becomes ready to complete. On a table hit, the physical address is immediately avail-

External channels allow the concurrent program to com- able. Otherwise it needs to fetch corresponding translation.

municate with external world (for instance, to send a packet For messages more than one page, process translateAddress

into the network). External channels are like regular chan- returns the physical address for each page. Then process

nels; the only di erence is that they have an external reader hostRequest makes a request to process networkSend to ac-

or a writer. tually send the page onto the network.

In the presence of nondeterminism (due to the alt state-

ment), the language guarantees fairness.2 When multiple

2.2 Fast Paths

channel operations are ready in an alt, if the implemen-

A path [26, 3] is a dynamic execution path in a program.

tation always chooses one particular channel operation, the

Typically, a small set of paths in the program account for a

processes waiting on the other channels can be starved out.

large percentage of its execution time.

This is referred to as unfairness. Fairness, therefore, implies

A fast path provides better performance to a set of com-

freedom from starvation. It should be noted that fairness

monly executing paths in the program. It should be empha-

does not imply that each of the enabled guarded statements

sized that a fast path is not necessarily a single execution

will be chosen with equal probability.3

path in the program. A fast path is typically a set of related

In additional to channel operations, the language supports

execution paths in the program.

the common control ow statements like if-then-else and

Traditionally, a fast path [30, 26, 23] consists of two com-

while statements. For simplicity, it supports just one type

ponents: A predicate that identi es a common case, and

of data: integers.

specialized code that is optimized to e ciently handle that

common case. As long as the predicate holds, executing the

1

Also known as rendezvous channels.

specialized code is functionally equivalent to the original ex-

2

Two types of fairness guarantees can be provided: weak

ecution path chosen without the fast path. It is formed by

fairness and strong fairness [2]. However, the fast path

extraction technique described in this paper preserves the extracting code fragments from several di erent modules.

fairness semantics for both these types. Consequently, we This allows fast paths to avoid module-crossing overheads;

do not make a distinction between the two in the rest of it also makes them more amenable to compiler optimiza-

this paper.

tions.

3

The term fairness is sometimes used in the operating

In this paper, we extend the traditional notion of a fast

systems community to imply this meaning. In this paper,

path to allow them to abort midway through the execution

we always use the term fairness to only imply starvation-

freedom. (Figure 4) for two reasons. First, it is often di cult to iso-

To Appear in the Proceedings of 13th ACM/IEEE International Conference on Parallel Architectures and Compilation Techniques (PACT 2004)

late the fast path with a single predicate that has to hold fastpath demo {

at the start of the fast path. Second, in some cases, a pred- process hostRequest {

icate might not hold at the start of the fast path but might statement hostSendRequestC as H0,

become true later. For instance, a DMA engine4 might not translateRequestC as H1

translateReplyC as H2,

be available at the start of the fast path but might become

dataSendC as H3,

available by the time it is needed at a later point on the fast #1;

path. start H0 ? (size

follows H1 ( H2 H3 )* ;

2.3 Scope exit #1;

}

To extract fast paths from programs, three questions need

process translateAddress {

to be answered.

statement translateRequestC as T1, #2;

1. How are fast paths selected? This requires knowledge start T1 H1;

about which paths in the program are critical as well exit T1;

as commonly executed. }

process networkSend {

2. How does the programmer specify the fast paths in

statement dataSendC, #3;

the program? The compiler will use this information

start dataSendC;

to aggressively optimize the fast path.

exit #3;

3. How does the compiler extract and optimize the fast }

path? }

In this paper, we address the last two questions: specify-

ing and optimizing fast paths. Identifying fast paths is an Note: #1, #2, and #3 name the rst statement after

independent problem that is not addressed here. In this pa- the point where they appear. The ? is used to specify a

per, we assume that the programmer identi es the fast paths predicate that has to hold at the statement. The

either based on knowledge of the application behavior or by is used to specify the statement in the other process with

using some recent work on path pro ling in sequential [3, 22] which it is communicating. The as allows the programmer

and parallel programs [11, 31]. The work presented in this to specify a shorter name for a statement.

paper can also simplify the task of identifying fast paths.

This is because a programmer (or even an automated tool)

can try out several di erent fast paths with little e ort to Figure 5: A Fast Path Example.

determine the most pro table fast path.

3. SPECIFYING FAST PATHS erful way of expressing control ow in programs and have

been widely used (Section 7).

Traditionally, fast paths in sequential programs are often

We will now illustrate our fast path speci cation language

speci ed by annotating the program to indicate the likely

with a fast path (Figure 5) in our example (Figure 2). Four

result (true or false) of conditional statements of the pro-

elds can be speci ed for each process involved in the fast

gram [27]. The HIPPCO [11] compiler allows a probability

path. The statement eld enumerates the list of all state-

to be speci ed for conditional statements. These probabil-

ments that are relevant to the fast path. The start eld

ities can be determined by program pro ling. Another ap-

speci es the starting statement element while the exit eld

proach [23] is to use a predicate to specify fast paths. The

speci es the statement element that marks the end of the

compiler then extracts the fast path code by partially eval-

fast path in that process. The follows eld is a regular

uating the code based on the predicate. Neither of these

expression on statement elements that speci es the set of

approaches meets our needs.

execution paths that the process can take between start

To specify fast paths in concurrent programs, we identi ed

and exit. The fast path is terminated if either the exit

three desirable properties that the fast path speci cation

element is satis ed or if it deviates from the path speci ed

mechanism should satisfy. First, the fast path speci cation

by the follows eld.

should be just hints to the compiler and, therefore, should

Three points are worth noting here. First, the follows

not a ect the correctness of the program. In addition, since

and exit elds are optional. Second, any statement that

they are just hints, the fast path speci cation should be

is not explicitly included in the statement eld has no im-

kept separate from the code to the extent possible. This

pact on whether or not an execution path is selected on the

would ensure that the speci cations do not make the code

fast path. This helps to keep the regular expression small.

less readable by cluttering it. Second, the fast paths should

For instance, in process translateAddress, the fast path is

have the ability to abort prematurely (Section 2.2). Finally,

aborted if it encounters statement #2 (Figure 5). However,

the speci cation should allow programmer to control the

statements involving operations on channel translateReplyC

scheduling of the di erent processes involved in the fast path

are simply ignored while determining if a particular path be-

since it can have a big impact on the performance. Note

longs to the fast path because it is not listed in the statement

that the traditional approaches described in the previous

eld. Third, the exit eld is redundant in process networkSend

paragraph do not satisfy these properties.

(Figure 5). This is because it speci es a null path expres-

This paper proposes using an extension of path expres-

sion for the follows eld. Consequently, the fast path would

sions [9, 8] to specify fast paths in concurrent programs. A

terminate if it encountered either of dataSendC or #3 af-

path expression is a regular expression over control points

ter starting the fast path as it would no longer satisfy the

in a program. Path expressions provide a succinct and pow-

follows eld.

4

A DMA engine allows a device to move bulk data e ciently. A statement element is the basic unit in the fast path

To Appear in the Proceedings of 13th ACM/IEEE International Conference on Parallel Architectures and Compilation Techniques (PACT 2004)

speci cation. In the simplest case, a statement element is The process-based approach [28, 15, 21] is the popular ap-

just a statement.5 A statement element can also qualify a proach to compile concurrent programs to run on sequen-

statement with one or more of the following. First, a predi- tial processors. In the process-based approach, the compiler

cate can be speci ed that has to hold at that statement. For generates the code for each process separately and inserts

example, the start condition in process hostRequest speci- additional code to periodically context switch between them

es that the predicate size ). Finally, it can explicitly specify the roughly the sum of the sizes of the individual processes.

scheduling decisions on the fast path and override the de- However, the generated code incurs a runtime overhead due

fault scheduling policy. to the concurrency. The runtime overhead stems from three

Our default scheduling policy works as follows: At the sources. First, a context switch involves saving the state of

start, all processes on the fast path that are ready to run the running process, and then retrieving the state of the next

(i.e. unblocked) are placed in a FIFO ready queue (in the process and running it. Second, when values are transferred

order the processes appear in the fast path speci cation). over a channel, there is overhead associated with it that is

The execution begins with the rst process on the queue similar to the overhead of passing parameters to a function.

and proceeds until a channel operation is encountered. If the Finally, nondeterministic statements require a mechanism

channel operation causes it to block, the next process from (like randomly picking between the available options) that

the ready queue is picked and executed. Alternately, if the guarantees fairness.

currently executing process communicates with a blocked The automata-based approach [10, 6, 12, 29] is a radically

process that is part of the fast path, the process performing di erent approach that uses symbolic execution to generate

the in (read) operation is the one that continues while the code for concurrent programs. Symbolic execution is a gen-

other process is added to the ready list. eral technique that has been applied in wide variety of areas

The default scheduling policy works well in practice be- including program testing, model checking, program anal-

cause it often re ects the critical path in the concurrent ysis, and optimization. In the automata-based approach,

program. For instance, the default policy picks the best symbolic execution is used to enumerate the control state

scheduling for the example in Figure 2 (which was extracted space of a concurrent program. We explain this brie y in

from a real program [21]). In addition, copy propagation op- the following paragraph (See [29] for a detailed description).

timization is very e ective with this policy because the pro- The automata-based approach essentially treats each pro-

cess reading from the channel is likely to use those values cess in the concurrent program as a state machine and com-

immediately. bines all the state machines in the program to generate a

In a few rare cases, di erent scheduling decisions (from single global state machine. Each statement in a process

the ones made by the default scheduling policy) at a few represents a state in the corresponding state machine. A

locations on the fast path can improve performance. We tuple consisting of the state of each of the various state ma-

provide a simple yet powerful mechanism to override the de- chines denotes a state of the global state machine. At each

fault scheduling decision. An element can be quali ed with step, the global state machine takes a state in one of the in-

a yield directive that allows the currently scheduled process dividual state machines. This is repeated until all the transi-

to specify a di erent process to be scheduled immediately. tions reachable from the start space are explored. It should

For instance, suppose (H2 yield translateAddress) were be noted that the nondeterminism in various processes of

used in the place of H2 in the follows eld of process the concurrent program gets translated into nondetermin-

hostRequest. In this case, after the communication on istic transitions in the global state machine. Consequently,

channel translateReplyC, process translateAddress would the global state machine is essentially a sequential program

be scheduled to run instead of process hostRequest. with nondeterminism.

The advantage of the automata-based approach is that

there are no context switches and channel operations in the

4. GENERATING FAST PATHS generated code. Although, there is still overhead involved

due to the nondeterminism, the code generated is extremely

4.1 Background fast. The disadvantage of this approach is that the global

state machine generated can be, in the worst-case, expo-

This paper focuses on the application domains that use

nential in the size of the individual state machines. Some

concurrency as a convenient way to structure programs even

optimization techniques [12, 11] alleviate the code blowup

on a uniprocessor (Section 1). Consequently, the most e -

problem by identifying and eliminating some of the dupli-

cient way to execute these programs is to run all its processes

cated code. Still, the code blowup remains exponential in

in the same virtual address space (i.e. single operating sys-

the worst-case.

tem process) and perform scheduling at the user level in

Edwards et al. [15] compared the two approaches on a set

the runtime system. There are two main approaches to im-

of Esterel programs. Esterel (Section 7) is a deterministic

plement this: process-based approach and automata-based

concurrent language. The study found that the automata-

approach.

based approach resulted in code that was twice as fast as

the process-based approach. However, the size of the code

5

Statements in a process are identi ed either using a chan-

generated by the automata-based approach was 2 3 orders

nel name (when the channel name uniquely identi es a

statement that performing an operation on it) or using of magnitude larger than that produced by the process-based

the # annotation. For instance, the #2 refers to the approach. Such a large increase in the size of generated code

rst statement in the body of the if statement in process is often unacceptable.

translateAddress.

To Appear in the Proceedings of 13th ACM/IEEE International Conference on Parallel Architectures and Compilation Techniques (PACT 2004)

4.2 Extracting Fast Paths

This paper proposes combining the two approaches so

that the generated code achieves the performance of the

automata-based approach while resulting in code size sim-

ilar to that from the process-based approach. The key in-

sight is that the best of the two approaches can be achieved

by using symbolic execution (similar to the automata-based

approach) to generate code for the fast paths and using the

process-based approach to generate code for the rest of the

concurrent code.

Our approach proposes generating code for the concurrent

program in three stages:

1. Process-based Baseline Code. The compiler uses

process-based approach to generate code for the program.

This portion of the code is a complete stand-alone imple-

mentation of the program.

2. Extracting Fast Path Code. The compiler uses the

fast path speci cation to generate code for the fast paths.

For each fast path speci ed, the compiler rst translates the

path expressions (one for each process involved) into nite-

state machines. Each state-machine includes a start state

and a normal exit state which corresponds to the start and

the end of the fast path. Then, the compiler uses sym-

bolic execution to follow all possible execution paths from

the start of the fast path. During the symbolic execution of Figure 6: Fast Path Extraction

each execution path, the compiler makes transitions in the

corresponding state machines each time an interesting lo-

cation6 is encountered in the program. The situation when

3. Entering and Exiting Fast Path. The process-based

such a transition is not available corresponds to a path that

code and the fast path code are then combined by adding

no longer matches the fast path speci cation. When this

code that transfer control to each other (Figure 4). In

happens, the execution point (where the violation is rst

the process-based code, code is inserted at the appropri-

detected) is marked as an abort point and that execution

ate points to check if the starting condition for the fast path

path is not longer executed symbolically. Similarly, if the

is satis ed and, if it is satis ed, transfer control to the fast

state machine reaches the normal exit state, the execution

path code. In the fast path code, code is added at the exit

point is marked as a normal exit point and that execution

points (normal exit and abort points) that return control to

path is terminated.

the process-based code.

Figure 6 illustrates the symbolic execution performed to

We need to do two things when transferring control be-

extract the fast path speci ed in Figure 5 for the example

tween the process-based code and the fast path code. First,

in Figure 2 & Figure 3. Each state in this gure includes

we need to update the program counter pointer for each

the program counter (line number from Figure 2) for each

involved process, this pointer identi es which instruction in

process in the fast path. The starting state (as speci ed in

the process is being executed. Second, each process has a

Figure 5) corresponds to the state (P1=13, P2=32, P3=50).

state variable that remembers which channel operations are

At each step, one of the processes is being symbolically exe-

ready in an alt; these state variables need to be updated.

cuted. For example, at state (P1=15, P2=41, P3=50), pro-

cess P2 is chosen to be executed. It symbolically executes

4.3 Process Scheduling on the Fast Path

the statement P2.size=P2.size-pageSize on line 41 and

A fast path usually involves multiple processes. There-

changes its program counter to 35. Two processes may

fore, process scheduling decisions have to be made during

also communicate. For example, at the start state (P1=13,

symbolic execution. Since the scheduling decisions have a

P2=32, P3=50), process P1 and P2 communicate on chan-

big impact on the performance, the programmer is allowed

nel translateRequestC. Therefore the two processes update

to precisely specify the scheduling decisions to be made on

their program counter and the executions enters the next

the fast path (Section 3).

state (P1=15, P2=35, P3=50). Any state in which one of

Our compiler uses the speci ed scheduling policy during

the processes has reached an end state or deviated from the

fast path extraction. As the start of the fast path, it puts

speci ed path is marked as an exit state or an abort state

all the processes involved in the fast path that are ready

respectively. No transition out of such a state is considered.

to be executed (i.e. unblocked) in a ready list (FIFO) and

For example, in state (P1=19, P2=32, P3=50), process P1

starts symbolically executing the rst one (say PA ). It fol-

has reached the exit state, so the symbolic execution does

lows this process until it encounters a channel operation or a

not proceed any further on this path.

yield directive to yield to a di erent process (say PB ) (Sec-

tion 3). At this point, there are three possibilities. First,

6

Recall that the fast path speci cation speci es all locations

in the program that are relevant to it. if it (PA ) encounters a channel operation and the channel

To Appear in the Proceedings of 13th ACM/IEEE International Conference on Parallel Architectures and Compilation Techniques (PACT 2004)

operation blocks, the symbolic execution picks up the next formance of fast path code.

process (say PC ) in the ready list and symbolically executes

it. Second, if the channel operation can complete and in- Enabling Traditional Optimizations. Traditional opti-

volves communication with another process (say PD ), one mizations, like copy propagation and dead code elimination,

of the two processes PA and PD is picked to be symbolically on fast paths result in program specialization and cross-

executed next (based on the scheduling decision speci ed) module optimizations. The fast path is composed of frag-

and the other is put in the ready list. Finally, if it (PA ) ments of code extracted from several processes. Since the

encounters a yield directive, PB is extracted from the ready code is executed only when the starting condition is sat-

list to be symbolically executed while PA is put on the ready is ed, the fast path code can be specialized assuming the

list. starting conditions. In addition, since process7 boundaries

are eliminated while extracting fast paths, the optimizations

4.4 Fairness on the Fast Path on fast paths are e ectively cross-module optimizations.

However, traditional optimizations cannot be directly ap-

The generated code is required to preserve fairness se-

plied to the fast paths in isolation. This is because their

mantics of the program (Section 2). Fast path involves code

control ow is linked back to the rest of the code via the

that is extracted from di erent processes and thereby makes

abort/exit points. To solve this problem, we need to prop-

some scheduling decisions. The compiler has to ensure that

agate some information back from each of the individual

it does not introduce starvation in the program. Starvation

processes to the fast paths. For instance, we perform live-

can arise from two situations. Either the speci ed fast path

variable analysis on the fast path in two stages. First, we

can be in nitely long (due to the presence of the repetition

perform live variable analysis in each of the processes. Sec-

operator in the path expressions). This can potentially al-

ond, this liveness information is propagated to each of the

low a fast path involving two processes to starve out a third

abort/exit point in the fast path depending on where the

process. Or it arises if the nondeterminism is not handled

exit/abort point in the fast path returns control to the var-

correctly on the fast path.

ious processes. Using this information, the liveness analysis

Our compiler employs a simple strategy to handle fair-

can be performed on the fast path.

ness: it simply relies on the underlying process-based code

that already handles fairness. To avoid starvation due to the

Speeding up fast path using lazy execution. Some

in nitely long fast paths, it places a bound (by maintaining

counters for each repetition operator) on how long the fast code can be eliminated by rearranging the sequence of exe-

path can execute and aborts the fast path if the bound is ex- cution on the fast path. For example, a lot of assignments

ceeded. Then the control would be returned to the process- are done on the fast path to mimic message passing between

based code which ensures fairness. To avoid starvation due processes to update their local variables. If the fast path is

to nondeterminism, the generated code periodically chooses taken to the end, some of these assignments might not be

not to execute the fast path code even when the starting necessary and can be eliminated using copy propagation.

conditions for that fast path are satis ed. Note that this However, these assignments might be necessary if the fast

is required for only those fast paths that include a nonde- path aborts. This can be addressed by using lazy execution.

terministic choice. This means that the process-based code By delaying these assignments until the points where the

that ensures fairness is executed a fraction of the time even fast path aborts, we can safely remove those assignments in

when the starting conditions for that fast path are satis ed. the middle of the fast path and improve performance.

This is su cient to ensure fairness in the generated code

even if the fast path code does not handle nondeterminism 5. IMPLEMENTATION

fairly.

To demonstrate the techniques described in this paper,

Our approach to handle fairness on the fast path is not

we have implemented the automatic fast path generation in

only simple but also presents an opportunity to avoid the

our ESP [21] compiler. ESP is a concurrent domain-speci c

overhead due to nondeterminism in the fast path. Recall

language designed to write rmware for programmable de-

that the nondeterminism ov



Contact this candidate