andygrove opened a new issue, #5990:
URL: https://github.com/apache/datafusion-comet/issues/5990

   ## Describe the bug
   
   `analyze_trace.rs` compares the native allocation counter against "the sum 
of per-thread Comet memory pool reservations" and reports points where 
allocation exceeds the pool total. The pool total is computed at 
`native/common/src/bin/analyze_trace.rs:164`:
   
   ```rust
   let pool_total: u64 = pool_by_thread.values().sum();
   ```
   
   That sum is not the total reserved. The per-thread counters come from 
`total_reserved_for_thread` (`native/core/src/execution/jni_api.rs:216`), which 
sums the pools registered on one thread and deduplicates shared pools **only 
within that thread**:
   
   ```rust
   let mut seen = HashSet::new();
   pools.values().filter_map(|p| {
       let ptr = Arc::as_ptr(p) as *const ();
       seen.insert(ptr).then(|| p.reserved())
   }).sum::<usize>()
   ```
   
   Task-shared pools are shared *across* threads, so every thread that 
references one reports its full reservation. Summing across threads therefore 
multiplies a task-shared pool's reservation by the number of threads 
referencing it.
   
   ## Evidence
   
   Measured on TPC-H SF100 (2 executors x 8 cores, Spark 4.1.1, 
`spark.memory.offHeap.size=16g`, tracing enabled, `jemalloc,alloc-accounting`), 
analysing the per-thread sum the same way this tool does:
   
   - `reserved / native` ratio reached **500x**. A pool cannot have reserved 
500 times what the allocator has handed out.
   - **27% of samples** reported reserved greater than native allocation.
   - Reserved was **0 at the median**, because threads with no registered pools 
contribute nothing and early samples see an empty map.
   - "Peak gap" landed on samples where reserved happened to be 0, so the 
reported peak was just peak allocation rather than a gap.
   
   Replacing the per-thread sum with a single process-wide total over the 
distinct entries of `TASK_SHARED_MEMORY_POOLS` changed the same traces 
substantially: max gap fell from 1694 MB to 560 MB, and the max ratio from 366x 
to 41x.
   
   ## Impact
   
   The tool's headline output, the points where allocation exceeds the pool 
total, is unreliable, and so is any gap figure derived from it. That includes 
at least one conclusion already recorded on #5934 ("moments with >1 GB native 
vs ~0 pool reservations"), which was produced this way.
   
   This is a documented tool, not a scratch binary: the contributor guide 
describes it and gives the command to run it 
(`docs/source/contributor-guide/tracing.md`). It is used to diagnose exactly 
the accounting questions tracked in #4576, so wrong numbers here are actively 
misleading.
   
   ## Suggested fix
   
   Emit one process-wide total and analyse against that, rather than summing 
per-thread counters:
   
   1. Add a helper that sums `reserved()` over the distinct entries of 
`TASK_SHARED_MEMORY_POOLS` (keyed by task attempt, so each pool is counted 
once).
   2. Log it as a single counter at the same point `native_allocated` is 
emitted (`jni_api.rs` ~1103), so both halves of a sample are true at the same 
instant.
   3. Have `analyze_trace.rs` anchor on that counter instead of 
`pool_by_thread.values().sum()`.
   
   Step 3 matters on its own: the counters are emitted in the order jemalloc, 
native, per-thread, total, so anchoring a sample on `native_allocated` pairs it 
with the previous group's total. That one-sample lag alone accounted for the 
difference between a 1694 MB and a 560 MB peak gap in the numbers above.
   
   I have a working 23-line patch for steps 1 and 2 from the investigation in 
#4576 and can turn it into a PR.
   
   ## Additional context
   
   Follows from the measurements posted on #4576. The per-thread counters 
remain useful for their original purpose, which is per-thread attribution in a 
trace viewer; the defect is only in summing them to obtain a process total.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to