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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

296 APPENDIX F. ANSWERS TO QUICK QUIZZESreaders, given that the rcu read lock() andrcu read unlock() primitives neither spin norblock?Answer:The modifications undertaken by a given RCUupdater will cause the corresponding CPU toinvalidate cache lines containing the data, forcingthe CPUs running concurrent RCU readers toincur expensive cache misses. (<strong>Can</strong> you design analgorithm that changes a data structure withoutinflicting expensive cache misses on concurrentreaders? On subsequent readers?)Quick Quiz 8.12:WTF??? How the heck do you expect me to believethat RCU has a 100-femtosecond overhead when theclock period at 3GHz is more than 300 picoseconds?Answer:First, consider that the inner loop used to take thismeasurement is as follows:1 for (i = 0; i < CSCOUNT_SCALE; i++) {2 rcu_read_lock();3 rcu_read_unlock();4 }Next, consider the effective definitions of rcu_read_lock() and rcu_read_unlock():1 #define rcu_read_lock() do { } while (0)2 #define rcu_read_unlock() do { } while (0)Consider also that the compiler does simple optimizations,allowing it to replace the loop with:i = CSCOUNT_SCALE;<strong>So</strong> the ”measurement” of 100 femtoseconds is simplythe fixed overhead of the timing measurementsdivided by the number of passes through the innerloop containing the calls to rcu_read_lock()and rcu_read_unlock(). <strong>And</strong> therefore, this measurementreally is in error, in fact, in error by anarbitrary number of orders of magnitude. As youcan see by the definition of rcu_read_lock() andrcu_read_unlock() above, the actual overhead isprecisely zero.<strong>It</strong> certainly is not every day that a timing measurementof 100 femtoseconds turns out to be anoverestimate!Quick Quiz 8.13:Why does both the variability and overhead ofrwlock decrease as the critical-section overheadincreases?Answer:Because the contention on the underlying rwlock_tdecreases as the critical-section overhead increases.However, the rwlock overhead will not quite dropto that on a single CPU because of cache-thrashingoverhead.Quick Quiz 8.14:<strong>Is</strong> there an exception to this deadlock immunity,and if so, what sequence of events could lead todeadlock?Answer:One way to cause a deadlock cycle involving RCUread-side primitives is via the following (illegal)sequence of statements:idx = srcu_read_lock(&srcucb);synchronize_srcu(&srcucb);srcu_read_unlock(&srcucb, idx);The synchronize_rcu() cannot return untilall pre-existing SRCU read-side critical sectionscomplete, but is enclosed in an SRCU read-sidecritical section that cannot complete until thesynchronize_srcu() returns. The result is a classicself-deadlock–you get the same effect when attemptingto write-acquire a reader-writer lock whileread-holding it.Note that this self-deadlock scenario does not applyto RCU Classic, because the context switch performedby the synchronize_rcu() would act as aquiescent state for this CPU, allowing a grace periodto complete. However, this is if anything evenworse, because data used by the RCU read-side criticalsection might be freed as a result of the graceperiod completing.In short, do not invoke synchronous RCU updatesideprimitivesfromwithinanRCUread-sidecriticalsection.Quick Quiz 8.15:But wait! This is exactly the same code that mightbe used when thinking of RCU as a replacement forreader-writer locking! <strong>What</strong> gives?Answer:This is an effect of the Law of Toy Examples:

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

Saved successfully!

Ooh no, something went wrong!