Would you like some syntactic sugar with your TBB? - PowerPoint PPT Presentation

About This Presentation
Title:

Would you like some syntactic sugar with your TBB?

Description:

Title: Would you like some syntactic sugar with your TBB? Author: Evan Driscoll Last modified by: David Wood University of Wisconsin Created Date – PowerPoint PPT presentation

Number of Views:58
Avg rating:3.0/5.0
Slides: 39
Provided by: EvanD152
Category:

less

Transcript and Presenter's Notes

Title: Would you like some syntactic sugar with your TBB?


1
Would you like some syntactic sugar with your TBB?
  • Evan Driscoll

2
What is TBB?
  • C library for writing concurrent programs
  • Classes for
  • Loop-based concurrency
  • Task-based concurrency
  • Pipelines
  • Concurrent data structures
  • Atomic types

3
TBB good?
  • Im excited
  • Integrates well with C
  • Large library, many paradigms
  • Broader than MapReduce, OpenMP

4
TBB syntax
  • Low-level syntax
  • templates, operator overloading, placement new
  • High-level syntax
  • Tons of boilerplate code
  • main.C in parallel_while othello went from 206 to
    424 lines (doing 3 loops), gt58 boilerplate
  • Separation of code
  • Loop bodies lexically moved

5
TBB syntax
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • / Recurse /
  • quality
  • Lookahead( b, other_color, newdepth )
  • if( quality gt nBest )
  • nBest quality

6
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • / Recurse /
  • quality
  • Lookahead( b, other_color, newdepth )
  • if( quality gt nBest )
  • nBest quality

parallel_whileltLookaheadMoveEvaluatorgt
w QueueGenerator g(moves) LookaheadMoveEvaluator
e(nBest, board, other_color, newdepth) w.run(g,
e)
7
class QueueGenerator queueltOthelloMovegt
_moves public QueueGenerator
(queueltOthelloMovegt moves) _moves(moves)
bool pop_if_present
(OthelloMove out_move)
if(_moves.empty()) return false else
out_move _moves.front()
_moves.pop() return true
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • / Recurse /
  • quality
  • Lookahead( b, other_color, newdepth )
  • if( quality gt nBest )
  • nBest quality

8
class LookaheadMoveEvaluator atomicltintgt
_nBest OthelloBoard const _board char
_otherColor int _newDepth public
LookaheadMoveEvaluator
(atomicltintgt nBest,
OthelloBoard const board,
char otherColor, int
newDepth) _nBest(nBest) ,
_board(board) , _otherColor(otherColor)
, _newDepth(newDepth)
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • / Recurse /
  • quality
  • Lookahead( b, other_color, newdepth )
  • if( quality gt nBest )
  • nBest quality

9
void operator() (OthelloMove move) const
OthelloBoard b _board b.applyMove(move)
int quality Lookahead( b,
_otherColor, _newDepth ) int curNBest
_nBest while(quality gt curNBest
_nBest.compare_and_swap
(quality, curNBest) ! curNBest)
curNBest _nBest typedef OthelloMove
argument_type
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • / Recurse /
  • quality
  • Lookahead( b, other_color, newdepth )
  • if( quality gt nBest )
  • nBest quality

10
But these transformations are all mechanical!
11
class QueueGenerator queueltOthelloMovegt
_moves public QueueGenerator
(queueltOthelloMovegt moves) _moves(moves)
bool pop_if_present
(OthelloMove out_move)
if(_moves.empty()) return false else
out_move _moves.front()
_moves.pop() return true
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • / Recurse /
  • quality
  • Lookahead( b, other_color, newdepth )
  • if( quality gt nBest )
  • nBest quality

12
class LookaheadMoveEvaluator atomicltintgt
_nBest OthelloBoard const _board char
_otherColor int _newDepth public
LookaheadMoveEvaluator
(atomicltintgt nBest,
OthelloBoard const board,
char otherColor, int
newDepth) _nBest(nBest) ,
_board(board) , _otherColor(otherColor)
, _newDepth(newDepth)
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • / Recurse /
  • quality
  • Lookahead( b, other_color, newdepth )
  • if( quality gt nBest )
  • nBest quality

13
class LookaheadMoveEvaluator atomicltintgt
_nBest OthelloBoard const _board char
_otherColor int _newDepth public
LookaheadMoveEvaluator
(atomicltintgt nBest,
OthelloBoard const board,
char otherColor, int
newDepth) _nBest(nBest) ,
_board(board) , _otherColor(otherColor)
, _newDepth(newDepth)
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • / Recurse /
  • quality
  • Lookahead( b, other_color, newdepth )
  • if( quality gt nBest )
  • nBest quality

14
So do this automagically
  • Extend the syntax of C
  • Implement a source-to-source transformation

15
So do this automagically
16
New syntax
  • tbb_shared new qualifier
  • Concept variable is shared between threads
  • Implementation a reference is used in the class

17
New syntax
  • concurrent_for(var , start , end , grainsize)
  • var can name an existing variable or declare a
    new one must be compatible with blocked_range
  • Iterates over start, end )
  • If omitted grainsize, uses auto_partitioner()
  • Cant specify different increments
  • Current status parses (and typechecks), but
    transformation incomplete

18
New syntax
  • cwhile_iterator type itervarconcurrent_while(con
    d) cwhile_generator genstmts
    bodystmts
  • Generates two classes
  • Generator (stream) class checks cond if true,
    runs genstmts
  • Body class runs bodystmts
  • Communicate via a cwhile_iterator
  • genstmts should write to itervar
  • bodystmts should read from itervar

19
New syntax
  • cwhile_iterator type itervarconcurrent_while(con
    d) cwhile_generator genstmts
    bodystmts
  • Current status implemented
  • Only minor restrictions no nested
    concurrent_while, types of variables used
    restricted

20
C elision
  • define
  • concurrent_while -gt while
  • cwhile_iterator -gt
  • tbb_shared -gt
  • concurrent_for(var, start, end, )
    -gt for(varstart, var ! end, var)
  • But doesnt work if var declares a variable

21
Othello revisited
concurrent_while( moves.size() gt 0 )
cwhile_generator move moves.front()
moves.pop() OthelloBoard b
board b.applyMove(move) int
quality Lookahead( b,
other_color, newdepth ) if( quality gt
nBest ) tbbspin_mutexscoped_lock
l ((tbbspin_mutex)lock)
if(quality gt nBest) nBest
quality
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • / Recurse /
  • quality
  • Lookahead( b, other_color, newdepth )
  • if( quality gt nBest )
  • nBest quality

22
What changed?
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • quality Lookahead( b, other_color, newdepth
    )
  • if( quality gt nBest )
  • nBest quality

23
What changed?
  • while( moves.size() )
  • b board
  • b.applyMove( moves.front() )
  • moves.pop()
  • quality Lookahead( b, other_color, newdepth
    )
  • if( quality gt nBest )
  • nBest quality

24
What changed?
  • while( moves.size() )
  • b board
  • OthelloMove move moves.front()
  • b.applyMove(move)
  • moves.pop()
  • quality Lookahead( b, other_color, newdepth
    )
  • if( quality gt nBest )
  • nBest quality

25
What changed?
  • while( moves.size() )
  • b board
  • OthelloMove move moves.front()
  • b.applyMove(move)
  • moves.pop()
  • quality Lookahead( b, other_color, newdepth
    )
  • if( quality gt nBest )
  • nBest quality

26
What changed?
  • while( moves.size() )
  • OthelloMove move moves.front()
  • moves.pop()
  • b board
  • b.applyMove(move)
  • quality Lookahead( b, other_color, newdepth
    )
  • if( quality gt nBest )
  • nBest quality

27
What changed?
  • while( moves.size() )
  • OthelloMove move moves.front()
  • moves.pop()
  • OthelloBoard b board
  • b.applyMove(move)
  • int quality Lookahead( b, other_color,
    newdepth )
  • if(quality gt nBest)
  • nBest quality

28
What changed?
  • concurrent_while( moves.size() )
  • cwhile_generator
  • OthelloMove move moves.front()
  • moves.pop()
  • OthelloBoard b board
  • b.applyMove(move)
  • int quality Lookahead( b, other_color,
    newdepth )
  • if( quality gt nBest )
  • tbbspin_mutexscoped_lock
    l((tbbspin_mutex)lock)
  • if(quality gt nBest)
  • nBest quality

29
Done!
  • concurrent_while( moves.size() )
  • cwhile_generator
  • OthelloMove move moves.front()
  • moves.pop()
  • OthelloBoard b board
  • b.applyMove(move)
  • int quality Lookahead( b, other_color,
    newdepth )
  • if( quality gt nBest )
  • tbbspin_mutexscoped_lock
    l((tbbspin_mutex)lock)
  • if(quality gt nBest)
  • nBest quality

30
Anything else?
  • includes for TBB headers
  • Removed declaration for OthelloBoard b and int
    quality
  • Added cwhile_iterator to definition of move
  • Added tbb_shared to definition of nBest
  • Added a declaration for the lock
  • Added another declaration of OthelloBoard b in
    another branch
  • Created a task_scheduler_init object in main

31
Anything else?
  • Changed CCg and LDg to use tbbetter driver
  • Added a I and L flag to the TBB directories
  • Added ltbb to the linker flags

32
Interesting point constness
  • Loop-carried dependencies wrong
  • This translates to not modifying thread-local
    variables
  • Any not marked tbb_shared!
  • Which iteration did the value come from?
  • Also applies to reading the value of a variable
    changed in the loop
  • TBB enforces operator() is const

33
Performance (othello, lookahead 7)
34
Wrapping up
  • Got some done more to do
  • Goals if this were a longer-term project (or if I
    hadnt procrastinated like mad)
  • Finish concurrent_for
  • Find a translation for parallel_reduce
  • Make cilk code compile
  • Goals for a serious project
  • Engineering on the parser
  • Bug squashing (still 7 or so outstanding 5
    patched by sed)
  • Integrate with other compilers
  • Improve edge cases
  • If you can do 80 of the job with 50 of the
    work, that is the right way

35
Questions?
36
Alternate syntax
  • Alternate names
  • cwhile_generator?!
  • Really easy to change
  • Updating test cases probably longer process
  • tbb_shared implies volatile?
  • Seems useful, but already broke

37
Alternate syntax
  • concurrent_while(iterator, cond)
  • Explicit as to what iterator is being used
  • Currently you must use exactly one variable
    declared with cwhile_iterator inside the body of
    each concurrent_while
  • concurrent_while() cwhile_generator
    cwhile_body

38
What really happens
othello.cc
cc1plus -E
modified elsa
sed
othello.o
cc1plus -E
cc1plus
as
Write a Comment
User Comments (0)
About PowerShow.com