1. Modify MemoryArena so that it just calls new for each memory allocation. (You will also want to record all pointer values returned by these new calls so that memory can be freed in the Reset() method.) Render images of a few scenes and measure how much more slowly pbrt runs. Can you quantify how much of this is due to different cache behavior and how much is due to overhead in the dynamic memory management routines?
  2. Change the BlockedArray class so that it doesn’t do any blocking and just uses a linear addressing scheme for the array. Measure the change in pbrt’s performance as a result. (Scenes with many image map textures are most likely to show any differences, since the MIPMap class is a key user of BlockedArray.)
  3. Try a few alternative implementations of the statistics system described in Section A.7 to get a sense of the performance trade-offs with various approaches. You might try using atomic operations to update single counters that are shared across threads, or you might try using a mutex to allow safe updates to shared counters by multiple threads. Measure the performance compared to pbrt’s current implementation and discuss possible explanations for your results.