Skip to content
Profiling & bottleneck analysis

Find out why your GPUs
cost more than they should.

Most AI workloads run far below what the hardware can do — and you can't fix what you can't see. Kernalin pinpoints exactly where your GPU time and money leak, names the bottleneck in plain terms, and hands your team the concrete fix. No guesswork, no faked numbers.

Available
Profiling capabilities

Telemetry that turns into a plan.

A profiler that dumps a thousand counters just moves the problem. Kernalin ranks kernels by device time, surfaces the numbers that decide whether you're compute- or memory-bound, and points at the specific kernel to fix. Every session is stored so you can compare runs across changes. Supported environments: timing, op profiles and memory-stats analysis run on any CUDA GPU. Occupancy, memory throughput, tensor-core utilization, bank conflicts, spills and coalescing come from Nsight Compute counters, which need bare-metal or your own GPUs; many cloud pods (RunPod included) deny counter access, and Kernalin then says so up front instead of guessing.
profiling · llama-decode · session #204 ● live
Kernel timeline ranked by device time
flash_attn_fwd compute 1.42 ms
rmsnorm memory 0.68 ms
rope_apply memory 0.41 ms
silu_mul memory 0.33 ms
kv_gather latency 0.21 ms
SM occupancy
78%
DRAM throughput
84%
Tensor-core util
61%
L2 hit rate
42%
Bottleneck: memory-bound

Low L2 reuse on rmsnorm — recommend shared-memory tiling + operator fusion.

Kernel timing

Rank every op and kernel by device time (torch.profiler) so the hot path is obvious. Works on any CUDA GPU.

Occupancy

See SM occupancy per kernel and where the launch configuration leaves the device idle. Needs Nsight counter access.

Memory throughput

DRAM and L2 traffic against speed-of-light, so you know when a kernel is memory-bound. Needs Nsight counter access.

Tensor-core utilization

How much of the math actually lands on tensor cores versus the general pipes. Needs Nsight counter access.

Run history

Every session is stored and comparable — profile the same workload across changes over time.
Honest-None reporting

If a metric can't be captured on your hardware or driver, Kernalin reports it as absent — not as a plausible-looking zero. A profiler you can't trust is worse than no profiler.

Compute- or memory-bound?

One picture answers the only question that matters.

Before you touch a line of code, you need to know which ceiling you're hitting. The roofline places every kernel against this GPU's bandwidth roof and compute peak — so a kernel living far under the diagonal is memory-bound, and faster math won't save it. Kernalin names the ceiling and shows the headroom a fix would recover.
Bandwidth roofCompute peakArithmetic intensityAttained vs. roof %Headroom estimate
kernalin · roofline A100 · TF32
ridge point memory bandwidth roof compute peak memory-bound compute-bound arithmetic intensity — FLOP / byte → attained TFLOP/s → after fusion → 71% of roof rmsnorm rope_apply gemv_tile matmul (tf32) flash_attn_fwd
Memory-bound flash_attn_fwd · 22% of roof · L2 reuse 0.31 fix: shared-mem tiling + fusion
Memory bottleneck analyzer

Seven dimensions of memory health.

Most GPU kernels are memory-bound, and "out of memory" is rarely the real story. The analyzer scores seven independent dimensions of how a workload uses VRAM and the memory hierarchy — then leads with the single action that recovers the most. Fragmentation and allocation churn come from PyTorch memory stats; the other five need hardware counters.
rnx memory · gemm_fwd · 7 dimensions
Reserved VRAM10.0 GB
allocated 47% stranded 30% free 23%
Fragmentation
30% of reserved VRAM stranded
HIGH
Uncoalesced access
18% bytes-per-sector efficiency
HIGH
Excessive allocations
5,000 allocs / iteration
HIGH
Cache locality
L2 hit rate 22%
HIGH
DRAM bandwidth
88% SOL — streaming
MODERATE
Bank conflicts
20% wavefront replays
MODERATE
Register spilling
5,000 local sectors
MODERATE
Top action

PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True — reclaim 2.79 GB stranded in split blocks.

Fragmentation

01

Reserved VRAM stranded across split blocks the allocator can no longer reuse.

fix PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True

Uncoalesced access

02

Low bytes-per-sector efficiency — warps touching scattered addresses.

fix Restructure access; vectorize loads

Excessive allocations

03

Thousands of allocs per iteration thrashing the caching allocator.

fix max_split_size_mb; reuse buffers

Cache locality

04

Low L2 hit rate from poor reuse of recently touched data.

fix Shared-memory tiling; operator fusion

DRAM bandwidth

05

Kernel streaming near speed-of-light with nothing left to hide latency behind.

fix Fuse to cut DRAM round-trips

Bank conflicts

06

Shared-memory wavefront replays from threads hitting the same bank.

fix Pad shared arrays; swizzle indices

Register spilling

07

Live values spilling to local memory when a kernel outgrows its register budget.

fix Trim live ranges; cap occupancy target
How a session reads

Problem, diagnosis, recommendation, proof.

Every profiling session resolves to the same four-step shape — so a finding is never a dead-end metric, but a change you can make and measure.
01

Problem

A kernel is slower than its arithmetic should allow.

02

Diagnosis

Memory-bound: L2 reuse is low and DRAM is near speed-of-light.

03

Recommendation

Shared-memory tiling plus operator fusion to cut the round-trip.

04 verified

Measured improvement

The fix is re-profiled and benchmarked — the gain is verified, not asserted.

Illustrative session. Numbers depend on your workload and hardware.

Early access is open

Stop guessing at your GPU.

Profile a real workload and get a named bottleneck with a concrete fix. Join the early-access program.