From pixels to pipelines.
Real-time rendering, software rasterisation and GPU compute. I work across the CPU–GPU boundary, with attention to frame time, memory traffic and synchronisation.
Explore rendering projectsI'm Jonathan Liu. I build rendering engines, GPU kernels and concurrent C++ infrastructure. My work centres on data locality, explicit synchronisation, resource lifetime and measuring the critical path.
Interested in graphics, GPU computing and low-latency C++ roles, including trading infrastructure.
Real-time rendering, software rasterisation and GPU compute. I work across the CPU–GPU boundary, with attention to frame time, memory traffic and synchronisation.
Explore rendering projectsI build and measure concurrent queues, cache-aware CPU kernels and asynchronous network services. Trading infrastructure is a career interest; these projects demonstrate the underlying systems work, not a production trading platform.
Explore systems projectsVulkan 1.3, SPIR-V, Compute Shaders, OpenGL, CUDA Kernel Optimisation, Real-time & Offline Rendering
C++17 (primary), C, Python, GLSL, Slang, CUDA C/C++, ARM Assembly
SIMDe / SSE / AVX2, oneTBB, OpenMP, std::atomic, CAS, Reference Counting, Warp Intrinsics, Boost.Asio
Nsight Systems/Compute/Graphics, RenderDoc, perf, ASan / TSan / UBSan, GDB/LLDB, Linux, Docker, CMake
A C++17 Vulkan 1.3 renderer with separate graphics, compute and transfer execution paths. I rebuilt blocking resource uploads around explicit residency, asynchronous transfer submission and deferred reclamation, using Nsight Graphics to inspect the critical path.
4.66ms
Worst-case frame time after upload-path redesign
Historical RTX 3080 Ti Laptop GPU · Windows / MSVC Release · validation disabled for timing. Same-scene worst-case comparison, not a 91× steady-state FPS claim.
A C++17 CPU renderer with 32 × 32 triangle-to-tile binning, scalar and portable SIMDe raster paths, and a BVH-based Monte Carlo path tracer. Tile ownership keeps framebuffer writes local; SIMD batches depth interpolation and perspective-correct weights while coverage and shading retain shared logic.
Recorded 9 October 2026: Apple M5 Pro, macOS arm64, AppleClang 21, Release. TBB was disabled; task scheduling was serial and SIMD used SIMDe on ARM, not native x86 AVX2.
Static Spot mesh, 5,856 input triangles, Phong shading, one point light, no sampled texture. 100 warm-up frames per path per run; 1024² percentiles pooled from three runs. Covered pixels: 13.9% at 1024², so this is not a full-screen overdraw test.
The timer surrounds draw(): clear, preparation, binning,
depth, interpolation, shading and in-draw allocations are included.
Loading, display, image encoding and file output are excluded.
This is draw latency, not full-application FPS; older Intel measurements are not the baseline.
7.790ms
SIMDe path · 1024 × 1024 · Apple M5 Pro
Release · serial scheduling · portable ARM SIMD. Coverage tests and fragment shading are not claimed to be fully vectorised.
My C++17 performance-engineering library, formerly libHPC. It brings together measured CPU memory-access experiments, a CUDA radix-sort pipeline, sparse storage and concurrent-container prototypes. I pair profiling with numerical checks and lifetime debugging; microbenchmark results are scoped to their workloads.
| Workload | Baseline → optimised | Ratio |
|---|---|---|
| 1024² FP32 matrix | 97.93 → 11.58 ms | 8.46× |
| 8192² transpose | 63.28 → 19.58 ms | 3.23× |
| Horizontal 17-tap blur | 15.72 → 3.46 ms | 4.55× |
| Xyx vertical-blur family | 25.74 → 15.91 ms | 1.62× |
| 1024² / 16²-kernel convolution | 111.08 → 42.55 ms | 2.61× |
| 1 GiB loop fusion | 16.40 → 8.04 ms | 2.04× |
| 512 MiB container lifecycle | 21.33 → 2.41 ms | 8.86× |
Recorded 7 October 2026: ten repetitions with random interleaving, 15 OpenMP threads, no affinity pinning. Convolution is single-threaded and combines 16 × 16 output tiles with four independent reduction chains.
Xyx combines SIMD, prefetching and interleaved accumulators; its 1.62× gain is relative to its own x-tiled baseline. A y-major tiled alternative was faster at 12.34 ms. Container lifecycle includes construction, zero-initialisation and destruction; it is not a random-access throughput measurement.
19 matrix, blur, transpose and convolution variants passed numerical checks on the benchmark inputs. These checks and sanitizer runs provide evidence for the exercised cases, not a proof that every input or interleaving is correct.
Apple M5 Pro, Release, unpinned. Throughput uses ten 100M-item runs. Ring medians: 14.4M / 10.9M / 4.80M handoffs/s for 1P1C / 2P2C / 4P4C; these are comparisons with this project's allocating reference-counted queue, not a claim to outperform established queue libraries.
Separate 4P4C latency test at an aggregate 1M handoffs/s offered load: ring / linked p99 = 667 ns / 3.63 µs; p99.9 = 64.83 / 439.50 µs. 100M handoffs, 999K samples. The open-loop interval starts at the planned push time and ends at consumer completion, so scheduling lateness and backpressure are included; it is not the execution time of one queue method.
Separate SPSC handoff p99: 209 / 709 ns (ring / linked). Count, sum, XOR and sample count were checked alongside timing. Debug regressions also use unique-value checks. Recorded tests and an 8-consumer, 8.59B-pop-attempt Release soak completed without recurrence of the previously observed failures; this is not a blanket ABA/race-freedom guarantee.
Queue benchmark source8.46×
97.93 → 11.58 ms · 1024 × 1024 matrices
Apple M5 Pro · macOS Release · 10-run median. Compared with this project's strided baseline, not a vendor BLAS implementation.
1.39B keys/s
500M uint32 keys · 360 ms aggregate kernel time · RTX 3080 Ti Laptop GPU. Not end-to-end transfer/allocation time; not remeasured on the Mac.
A microservice messaging platform with Boost.Asio TCP long-connections, gRPC inter-service communication, custom TLV binary protocol with compile-time safety constraints, with a separately benchmarked TCP connection layer.
5.44ms
p99 round-trip time · loopback test
Historical isolated TCP-layer run: 17.9M request-response exchanges. Not full-service throughput, one-way message rate or production-network latency.
Bare-metal bring-up on Cortex-A72 (Raspberry Pi 4B): assembly boot, MMU configuration, interrupt subsystem, and cooperative scheduling — debugged through JTAG, GDB, and UART tracing.
Kernel → user-space transition
Cortex-A72 · Raspberry Pi 4B
Seeking graphics, GPU-compute and C++ performance/systems roles, including low-latency trading infrastructure. Open to opportunities in Shanghai and across the APAC region.