Parth Kumar Sinha

Mr. Parth Kumar Sinha

orcid

Research Focus & Metrics

Academic Career Length

1Year (2026-Present)

(Calculated once Scilit publication data is synced: current year − year of first publication + 1)

Representative Publications

View All Publications
14 September 2026 in Preprints.org
Verified
Preprint
Open access
PDF file
PSParth Kumar Sinha
Parth Kumar Sinha
Kernel-bypass storage designs built on Linux io_uring’s IORING_SETUP_SQPOLL mode are motivated by a simple argument: a dedicated kernel polling thread removes the per-operation syscall that blocking and non-polling asynchronous I/O interfaces pay, so on modern NVMe hardware, where flash latency is no longer the bottleneck, SQPOLL should win on throughput. We built ringio, a header-only C++20 storage engine around this argument, and tested it against libaio and plain io_uring (no SQPOLL) on a virtualized cloud NVMe device across two machine sizes (4 and 16 vCPUs) and a swept queue-depth and thread-count matrix, alternating 4KB random reads and writes. The argument does not hold once the device itself saturates: at matched thread count and queue depth, SQPOLL does not beat the syscall-based baselines on raw IOPS at either machine size once concurrency is high enough to reach the device’s roughly 200K-IOPS ceiling, ruling out core oversubscription as the explanation for that plateau. Below the plateau, at a single thread, the gap is starker still: libaio reaches more than double SQPOLL’s throughput on the same hardware, a gap that widens rather than narrows on the wider box. SQPOLL’s tail latency also degrades under more available cores rather than improving. What SQPOLL does deliver is a large reduction in kernel entries per completed operation, roughly an order of magnitude fewer than plain io_uring at high queue depth, at the cost of that added tail latency. Reading this alongside two recent studies that do report SQPOLL wins in CPU-bound settings, our results are consistent with a resolution neither we nor they test directly: SQPOLL’s advantage is conditional on the CPU or syscall path being the bottleneck, and it disappears once a saturated device becomes the limit first. A sweep of sq_thread_idle across four orders of magnitude leaves throughput, tail latency, and kernel entries per operation unchanged, ruling that parameter out as the explanation: the poller never reaches its idle timeout under this workload. We report the full methodology, including a page-cache measurement defect that invalidated an earlier round of results, and discuss what this suite’s data does and does not establish about the underlying cause.

14 September 2026 in Preprints.org
Verified
Preprint
Open access
PDF file
PSParth Kumar Sinha
Parth Kumar Sinha
The in-memory write buffer of an LSM-tree key-value store is searched on every read and written on every insert, so its cost per operation sets a floor on the whole engine. RocksDB uses a concurrent skip list, which chases pointers across independently allocated nodes and evaluates one data-dependent branch per key comparison. We present Aparajita, a MemTable representation that replaces the skip list with a list of cache-line-sized nodes, each holding fifteen 32-bit order-preserving key surrogates and a sentinel in one line, searched by a branchless SIMD kernel. Three design decisions carry the result. A relational vector compare over a sorted node yields a mask whose population count is the lower bound directly, so ordered search costs one compare, one movemask and one popcount with no branch. Surrogates are taken after the node’s shared prefix rather than from the start of the key, without which an absolute surrogate takes one value across all 200,000 keys in five of eight realistic distributions, including the keyspace this paper’s own evaluation runs on. Nodes are append-only, and the sorted order over their slots is a 64-bit word, so an insert is two stores into a free slot followed by one release store that publishes them. We implement Aparajita as a RocksDB plugin selectable by name without patching RocksDB sources, and evaluate it against the default skip list and VectorRep on a 12-core Emerald Rapids host. Point lookups over a resident MemTable are 22% to 39% faster than the skip list at 1, 4, 16 and 64 threads, non-overlapping across five runs per configuration at every point but one, backed by 55% fewer retired instructions and 40% fewer L1 misses per lookup. Ordered seeks are 15% to 29% faster, but a seek followed by ten iterator steps is 3% to 4% slower, and the representation charges 1.4 times the skip list’s arena per key. The skip list is 48% to 52% slower on insert at the representation level, and Aparajita is 18.8% faster in single-threaded db_bench, but the multi-threaded db_bench write path is bounded by RocksDB’s write group rather than by the MemTable: an insert there retires over 22,000 instructions in both representations. We report that ceiling rather than a write scaling claim the data does not support.

15 September 2026 in Preprints.org
Verified
Preprint
Open access
PDF file
PSParth Kumar Sinha
Parth Kumar Sinha
A long simulation that checkpoints its random generator and resumes on a different machine is relying on a property that std::mt19937 does not have. The C++ standard fixes the text format of an engine’s stream operators only partially, and the three major standard libraries disagree on both the numeric base of the digits and the order of the 624 state words. A checkpoint written under libstdc++ fails to load under the MSVC standard library, and loads without any diagnostic, at the wrong position,under libc++. This paper describes vphilox, a header-only C++20 library that removes the failure by changing what is stored. The generator is Philox4x32-10, a counter-based construction whose entire state is a key and a position, so a checkpoint is six 32-bit integers and a word offset, not a snapshot of engine internals. The same property gives constant-time seek and gives each worker an independent substream with no coordination, so a task draws the same numbers whatever the thread count and schedule. The cost of those properties is the question the design has to answer, because the earlier attempt to adopt Philox in a production machine-learning library was rejected on the grounds that scalar Philox runs at one tenth the speed of the Mersenne Twister. We report that the tenfold penalty did not reproduce on any of five processors measured, and that interleaving independent counters across SIMD lanes brings the generator to between 0.22× and 0.75× the cost per byte of std::mt19937 on the bulk path. Aggregate cost per byte is flat across thread counts, and the first parallel limit we find is hyperthread co-location, not the generator.

4 September 2026 in Research Square
Verified
Preprint
Open access
PDF file
PSParth Kumar Sinha
Parth Kumar Sinha
Cache-coherence traffic across NUMA sockets, not the choice of lock-free algorithm, is the dominant cost in a shared-counter multi-producer multi-consumer (MPMC) queue once threads span more than one socket. Per-node sharding plus batched cross-node transfer is a known pattern, not a new algorithm; this paper is a case study of building one such queue, NumaRing, and of two profiling-driven bugs and one textbook optimization that made it worse, all found by measuring rather than assuming. Caching a per-operation topology lookup that turned out to cost 183 ns (eleven to twenty times the ring-buffer operation it gated) cut that cost by 61x and raised low-contention throughput 6 to 7x. A second bug in the cross-node work-stealing path, a shared atomic that every thread touched on every overflow, cut median latency at 32 threads by 202-fold once fixed. CPU-pause backoff, the standard fix for a contended compare-and-swap retry loop, cost 17 to 30 percent of raw throughput under true sustained contention instead of helping; we measured it, reverted it, and report why. The evaluation runs on a two-socket, 32-vCPU cloud instance, the largest topology a fixed compute quota let us reach, and we caught our own cross-host measurement error before trusting a number from it. Raw throughput at 32 threads stayed far below the project's original design target, and nothing in the data says another round of fixes like these closes that gap on two sockets. Code, evaluation data, and the exact commits behind every before/after number in this paper are public.