ioxide: update to 0.4.161, add h2/h3 and static-tls - #1094
Conversation
|
/benchmark -f ioxide --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFramework:
Full log |
|
/benchmark -f ioxide -t json-tls --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFramework:
Full log |
|
/benchmark -f ioxide -t static-tls --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
|
/benchmark -f ioxide -t baseline-h2 --save |
|
/benchmark -f ioxide -t static-h2 --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
|
/benchmark -f ioxide -t baseline-h3 --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
|
/benchmark -f ioxide -t static-h2 --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
1 similar comment
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFramework:
Full log |
Benchmark ResultsFramework:
Full log |
|
/benchmark -f ioxide -t baseline-h2 --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFramework:
Full log |
|
/benchmark -f ioxide -t static --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFramework:
Full log |
f50a473 to
3a57e03
Compare
|
/benchmark -f ioxide -t static --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFramework:
Full log |
|
/benchmark -f ioxide -t json-tls --save |
Benchmark ResultsFramework:
Full log |
|
/benchmark -f ioxide -t static-h3 --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFramework:
Full log |
|
/benchmark -f ioxide --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
|
|
- ioxide 0.0.8 -> 0.4.161; add ioxide.nghttp2/ngtcp2/nghttp3, drop ioxide.tls (folded into core) - migrate renamed APIs (ServerConfig.Tcp, TcpConnection, TcpHandle, RecvSlots) - TLS is OpenSSL both ways, the fastest backend on loopback (was kTLS TX) - h2 over TLS (nghttp2) on :8443, HTTP/3 over QUIC (ngtcp2+nghttp3) on udp:8443 - shared h2/h3 routes (baseline2, static) in Multiplexed - subscribe to static-tls, baseline-h2, static-h2, baseline-h3, static-h3
The benchmark showed json-tls down 16.9% under OpenSSL both ways: on a saturated 64-core rig the encrypt-into-slab TX path is CPU-bound where kTLS TX (kernel makes the records on send) is not. Restore KernelTx=true for the h1 and h2 contexts; RX stays userspace (OpenSSL). h1 write path returns to plaintext-into-slab. Locally h2 baseline2 rose 66k->211k req/s.
The kTLS path clears MSG_WAITALL at the handoff; the plaintext path kept it. Clear it there too via the public SendOpFlags property (no nuget change) - static-tls (WAITALL off) read above static (WAITALL on) under saturation, so drop it on plaintext and let the bench decide.
Reverts the plaintext WAITALL clear: a controlled A/B (raw TCP, 12 reactors) has WAITALL on faster by 3-10%, and clearing it on the arena moved static 0% (919,579 vs 920,007 at 1024 conns). The static-tls > static reading was a cross-run artifact, not a WAITALL effect.
Add KernelRx=true to both TLS contexts so inbound decrypts in the kernel too - recv delivers plaintext into ring memory, TlsSession.Decrypt is a passthrough, and the h2 dual pipe uses the kernel reader. Experimental (the RX handoff races ~1 first connection in 12 on some kernels); this is to measure how full kTLS compares against the hybrid.
The h2/h3 static routes served identity bodies while the client sends Accept-Encoding: br - so static-h2 shipped app.js at 204KB where the h1 path serves the 47KB .br, and static-h3 saturated on the oversized bodies. Cache the .br/.gz variants at startup and serve them by Accept-Encoding with a content-encoding header, matching the h1 path. Verified: h2 app.js 6.4k->16.7k req/s, body 204KB->47KB + content-encoding: br.
0.4.167 made ioxide.file io_uring reads only - it hands out a descriptor and a length, and no longer bakes HTTP responses or caches bytes. So Asset.Response is gone and StaticAssets takes no maxCachedFileBytes, and the h1 static path had to move rather than merely compile. It moved to the fast one. HttpSession frames the response header (the content type is HTTP's business, so it belongs here) and hands the descriptor to the handler, which reads the file STRAIGHT INTO the connection's write slab right behind that header - IORING_OP_READ, no reader buffer, no copy - so header and body leave in a single flush. Measured in the ioxide repo at 4 KiB on one saturated reactor, skipping the copy is worth 1.22x throughput and 0.82x CPU per request. That is legal on :8081 and :8443 because kTLS transmit is on: with the kernel making the records, the slab is SUPPOSED to hold plaintext. It would not be legal under OpenSSL transmit, where the slab must hold ciphertext - which is why this is a per-deployment property, not a free win. h2/h3 are untouched here on purpose: Multiplexed loads every asset with File.ReadAllBytes at startup and serves from memory, so they do no I/O per request at all. ReadFileAsync would be a regression there. h2 switches from nghttp2 to the pure-C# ioxide.http2 - three type names, no native library. Measured in the ioxide repo at 2 reactors, 64 connections, 32 streams, a 2-byte body: 2.46x nghttp2 over TLS at about a third of the CPU per request. Two caveats worth carrying: the lead narrows as reactors rise and connections-per-reactor falls (2.76x at 2 reactors, 1.48x at 16), and a 2-byte body measures framing and HPACK rather than moving data, so the arena's real payloads may not see the same margin. Verified: static bytes checksum-identical to disk over plaintext, over TLS h1 and over h2; 60 concurrent fresh TLS connections and 60 plaintext, 200 on all 120, no server errors.
ef28e2f to
93c8117
Compare
|
/benchmark -f ioxide --save |
|
👋 Benchmark request received. A collaborator will review and approve the run. |
Benchmark ResultsFramework:
Full log |
Updates the
ioxideengine entry to the latest ioxide and opens up the protocol tests it can now serve.0.0.8→0.4.161— addsioxide.nghttp2/ngtcp2/nghttp3, dropsioxide.tls(folded into core). Migrates the renamed APIs (ServerConfig.Tcp,TcpConnection,TcpHandle,RecvSlots).tlsmodule.:8443, HTTP/3 over QUIC (ngtcp2 + nghttp3) onudp:8443. Shared/baseline2and/static/*routes for both live inMultiplexed.cs.static-tls,baseline-h2,static-h2,baseline-h3,static-h3.Verified locally against the harness tools: h2load
/baseline22000/2000 2xx at 66k req/s, static-h2 148k req/s (1.13 GB/s), h3x/baseline2260k req/s; h1 and h1-TLS json/static unchanged.