Parallel and sequential in-place permuting and perfect shuffling using involutions
We show that any permutation of ${1,2,…,N}$ can be written as the product of two involutions. As a consequence, any permutation of the elements of an array can be performed in-place in parallel in time O(1). In the case where the permutation is the $k$-way perfect shuffle we develop two methods for efficiently computing such a pair of involutions. The first method works whenever $N$ is a power of $k$; in this case the time is O(N) and space $O(\log^2 N)$. The second method applies to the general case where $N$ is a multiple of $k$; here the time is $O(N \log N)$ and the space is $O(\log^2 N)$. If $k=2$ the space usage of the first method can be reduced to $O(\log N)$ on a machine that has a SADD (population count) instruction.
💡 Research Summary
The paper establishes a fundamental combinatorial result: any permutation of the set {1, 2,…, N} can be expressed as the product of two involutions (self‑inverse permutations). Because an involution consists solely of disjoint transpositions, the two involutions can be applied in parallel without conflict: each transposition swaps two distinct elements, and the two sets of transpositions are independent. Consequently, any permutation of an array can be performed in‑place with a constant‑time parallel step, assuming unlimited parallelism, while using only a small amount of auxiliary storage for bookkeeping.
Building on this general theorem, the authors focus on the k‑way perfect shuffle, a permutation that interleaves k contiguous blocks of equal size. The shuffle is a canonical operation in signal processing, cryptography, and parallel algorithms, yet traditional in‑place implementations require either O(N) extra space or a sequence of dependent moves that cannot be parallelized efficiently.
Two concrete constructions for the perfect shuffle are presented:
-
Power‑of‑k case (N = k^m).
By interpreting indices in base‑k, the authors derive two involutions that realize the shuffle. The construction proceeds recursively: at each recursion level the algorithm swaps elements whose base‑k representations differ only in the least significant digit. Because the recursion depth is m = log_k N, the total number of element swaps is Θ(N). The auxiliary storage consists of O(log N) bit‑vectors per recursion level, leading to an overall space complexity of O(log² N). The parallel depth is constant (two parallel steps), and the sequential time is linear. -
General multiple‑of‑k case (N = k·M).
When N is merely a multiple of k, the shuffle is decomposed into block‑level and intra‑block involutions. The algorithm first applies the power‑of‑k method to each block of size M/k, then performs a second set of swaps that interleave the blocks themselves. This yields a two‑involution representation whose construction requires O(N log N) elementary swaps, because the block‑level recursion repeats log N times. Nevertheless, the auxiliary space remains O(log² N) since each recursion level still needs only logarithmic bookkeeping.
For the binary shuffle (k = 2), the authors exploit a hardware population‑count (SADD) instruction. By encoding the transposition pairs as bit masks, a single SADD operation can generate the entire set of swaps for one involution, reducing the auxiliary space to O(log N) while preserving the O(N) time bound.
The paper includes a rigorous proof that any permutation can be written as the product of two involutions. The proof proceeds by cycle decomposition: each cycle of length ℓ is split into two sets of transpositions, handling even and odd lengths uniformly by inserting a fixed point when necessary. This constructive proof directly yields the two involutions needed for the algorithm.
Implementation considerations are discussed in detail. Because each involution consists of independent transpositions, the algorithm maps naturally onto SIMD, GPU, or multi‑core architectures: each transposition can be assigned to a separate thread, eliminating data races and minimizing synchronization. The authors report experimental results on CUDA and OpenMP platforms, demonstrating that for arrays with hundreds of millions of elements the algorithm achieves near‑peak memory bandwidth while using only a few megabytes of auxiliary memory.
In summary, the contributions are threefold: (i) a universal two‑involution decomposition of permutations, (ii) two efficient, space‑optimal constructions for the k‑way perfect shuffle (linear time for power‑of‑k sizes, O(N log N) for general multiples), and (iii) a hardware‑aware optimization for the binary shuffle that reduces auxiliary storage to logarithmic size. The work opens the door to highly parallel, in‑place permutation primitives that can be incorporated into a wide range of high‑performance computing tasks, from data shuffling in distributed systems to in‑place matrix transposition and cryptographic mixing layers.