10.07.2015 Views

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

292 APPENDIX F. ANSWERS TO QUICK QUIZZESis left as an exercise for the reader.Quick Quiz 5.9:The tandem double-ended queue runs about twiceas fast as the hashed double-ended queue, evenwhen I increase the size of the hash table to aninsanely large number. Why is that?Answer:The hashed double-ended queue’s locking designonly permits one thread at a time at each end,and further requires two lock acquisitions for eachoperation. The tandem double-ended queue alsopermits one thread at a time at each end, and inthe common case requires only one lock acquisitionper operation. Therefore, the tandem double-endedqueue should be expected to outperform the hasheddouble-ended queue.<strong>Can</strong> you created a double-ended queue that allowsmultiple concurrent operations at each end? <strong>If</strong> so,how? <strong>If</strong> not, why not?Quick Quiz 5.10:<strong>Is</strong> there a significantly better way of handlingconcurrency for double-ended queues?Answer:Transform the problem to be solved so that multipledouble-ended queues can be used in parallel,allowing the simpler single-lock double-endedqueue to be used, and perhaps also replace eachdouble-ended queue with a pair of conventionalsingle-ended queues. Without such “horizontalscaling”, the speedup is limited to 2.0. In contrast,horizontal-scaling designs can enable very largespeedups, and are especially attractive if there aremultiple threads working either end of the queue,because in this mulitiple-thread case the dequesimply cannot provide strong ordering guarantees.<strong>And</strong> if there are no guarantees, we may as wellobtain the performance benefits that come withrefusing to provide the guarantees, right?Quick Quiz 5.11:<strong>What</strong> are some ways of preventing a structure frombeing freed while its lock is being acquired?Answer:Here are a few possible solutions to this existenceguarantee problem:1. Provide a statically allocated lock that is heldwhile the per-structure lock is being acquired,which is an example of hierarchical locking (seeSection 5.4.3). Of course, using a single globallock for this purpose can result in unacceptablyhigh levels of lock contention, dramatically reducingperformance and scalability.2. Provide an array of statically allocated locks,hashing the structure’s address to select thelock to be acquired, as described in Chapter 6.Given a hash function of sufficiently high quality,this avoids the scalability limitations of thesingleglobal lock, butinread-mostlysituations,the lock-acquisition overhead can result in unacceptablydegraded performance.3. Use a garbage collector, in software environmentsproviding them, so that a structurecannot be deallocated while being referenced.This works very well, removing the existenceguaranteeburden (and much else besides) fromthe developer’s shoulders, but imposes the overheadof garbage collection on the program. Althoughgarbage-collection technology has advancedconsiderably in the past few decades, itsoverhead may be unacceptably high for someapplications. In addition, some applications requirethat the developer exercise more controloverthelayoutandplacementofdatastructuresthan is permitted by most garbage collected environments.4. As a special case of a garbage collector, use aglobal reference counter, or a global array ofreference counters.5. Use hazard pointers [Mic04], which can bethought of as an inside-out reference count.Hazard-pointer-based algorithms maintain aper-thread list of pointers, so that the appearanceof a given pointer on any of these lists actsas a reference to the corresponding structure.Hazard pointers are an interesting research direction,but have not yet seen much use in production(written in 2008).6. Use transactional memory (TM) [HM93,Lom77, ST95], so that each reference and modificationto the data structure in question isperformed atomically. Although TM has engenderedmuch excitement in recent years, andseems likely to be of some use in productionsoftware, developers should exercise some caution[BLM05, BLM06, MMW07], particularly

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!