Dynamic Diffracting Trees
A shared counter is a concurrent object which provides the fetch-and-increment operation on a distributed system. Recently, diffracting trees have been introduced as shared counters which work well under high load. They efficiently divide high loads into lower loads that can quickly access lock-based counters that share the overall counting. Their throughputs have surpassed all other shared counters when heavily loaded. However, diffracting trees of differing depths are optimal for only a short load range. The ideal algorithm would scale from the simple queue-lock based counter to a collection of counters with a mechanism (such as a diffracting tree) to distribute the load. In this thesis, we present the dynamic diffracting tree, an object similar to a diffracting tree, but which can expand and collapse to better handle current access patterns and the memory layout of the object's data structure, providing true scalability and locality. This tree then assumes each diffracting tree over its optimal range, from the trivial diffracting tree, a lock-based counters, to larger trees that have a collection of lock-based counters. This reactive design pushes consensus to the leaves of the tree, making agreement easier to achieve. It does so by taking advantage of cache-coherence to keep agreement at the higher contention areas of the tree. Empirical evidence, collected on the Alewife cache-coherent multiprocessor and a distributed shared-memory simulator, shows that the dynamic diffracting tree provides throughput within a constant factor of optimal diffracting trees at all load levels. It also shows to be an effective competitor with load balancing algorithms in produce/consumer applications. We believe that dynamic diffracting trees will provide fast and truly scalable implementations of many primitives on multiprocessor systems, including shared counters, k-exclusion barriers, pools, stacks, and priority queues.