Skip to the content.

Parallel Fenwick Tree

Team Members: Tzu-Yen Tseng (tzuyent) & Jim Shao (chiatses)

Project Web Page

https://erictsengty.github.io/ParallelFenwickTree


Summary

We are implementing a parallelizable Fenwick Tree (Binary Indexed Tree) on CPU to enable concurrent read and write operations.


Background

While segment trees and prefix sums have been widely studied in parallel computing, Fenwick trees remain relatively unexplored. As a lightweight data structure supporting range queries, a parallel Fenwick tree could offer performance benefits with lower overhead. A pseudocode of standard serial implementation is as follows:

class FenwickTree {
    int agg[n]; // Internal array

    // Add val to array[x]
    void add(int x, int val) {
        for (++x; x < n; x += x & -x) {
            agg[x] += val;
        }
    }

    // Get prefix sum of array[0..x-1]
    int sum(int x) {
        int res = 0;
        for (++x; x > 0; x -= x & -x) {
            res += agg[x];
        }
    }
    return res;
};

A straighforward parallelization approach is to use a fine-grained lock on each agg[i]:

class FenwickTree {
    int agg[n]; // Internal array
    lock_t locks[n];

    // Add val to array[x]
    void add(int x, int val) {
        for (++x; x < n; x += x & -x) {
            locks.lock();
            agg[x] += val;
            locks.unlock();
        }
    }

    // Get prefix sum of array[0..x-1]
    int sum(int x) {
        int res = 0;
        for (++x; x > 0; x -= x & -x) {
            locks.lock();
            res += agg[x];
            locks.unlock();
        }
    }
    return res;
};

Another simple alternative is to use atomic variables:

class FenwickTree {
    atomic<int> agg[n]; // Internal array

    // Add val to array[x]
    void add(int x, int val) {
        for (++x; x < n; x += x & -x) {
            agg[x] += val;
        }
    }

    // Get prefix sum of array[0..x-1]
    int sum(int x) {
        int res = 0;
        for (++x; x > 0; x -= x & -x) {
            res += agg[x];
        }
    }
    return res;
};

The Challenges


Resources


Goals and Deliverables

Plan to Achieve

Hope to Achieve


Platform Choice


Schedule

Date Goal
4/1 Build multi-versions of parallelizable Fenwick tree, focusing on parallelism across operations
4/3 Build the framework for microbenchmarking
4/6 Tune and finalize data-parallel approaches based on profiling results.
4/8 Develop and begin testing pipelining approaches
4/15 (Check-in) Finalize the pipelining approaches based on profiling results
4/22 Benchmark all approaches and compare the results
4/29 Complete the final report and poster

Last Updated: March 26, 2025