Commit d100fc3c authored by jan.koester's avatar jan.koester
Browse files

perf

parent b569f535
Loading
Loading
Loading
Loading
+4 −2
Changes for src/posix/udp.cpp: 4 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -649,8 +649,10 @@ int recvBatchRaw(SOCKET sock, int batch, bool gro_enabled) {
        }
    }

    struct timespec timeout = {0, 0}; // non-blocking
    int received = ::recvmmsg(sock, g_recv_msgs, batch, MSG_DONTWAIT, &timeout);
    // No timeout: MSG_DONTWAIT is what makes this non-blocking. The kernel
    // checks a timeout after every datagram, so a zero one ends the call after
    // the first and every "batch" is exactly one datagram however many queued.
    int received = ::recvmmsg(sock, g_recv_msgs, batch, MSG_DONTWAIT, nullptr);
    quicPerf().recvmmsg_calls.fetch_add(1, std::memory_order_relaxed);
    if (received < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
        quicPerf().recv_eagain.fetch_add(1, std::memory_order_relaxed);
+4 −9
Changes for src/quic.cpp: 4 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -122,15 +122,10 @@ ThreadPool& quicDispatchPool() {
// just cause cache-line/AES-NI-unit contention between worker threads for
// no benefit — sized near physical core count instead.
//
// Off by default: batch-size measurement on this sandbox's loopback bulk
// benchmark showed recvmmsg batches are essentially always exactly 1
// datagram (a single CPU-bound consumer thread never lets the kernel queue
// build up any deeper — see project memory), meaning there is nothing to
// fan out across on THIS workload regardless of how much decrypt costs.
// This is built for deployments where real network jitter/bursty delivery
// produces genuinely multi-packet batches, which this sandbox cannot
// reproduce to validate a throughput gain against — hence opt-in
// (QUIC_PARALLEL_DECRYPT=1) rather than a new default.
// Off by default (QUIC_PARALLEL_DECRYPT=1 enables it): on the loopback bulk
// benchmark, with GRO batches of ~24 packets, the fan-out costs more than it
// saves, 270 MB/s against 800+ without. Each packet is one task, which is far
// too fine-grained for a decrypt of under a microsecond per KB.
ThreadPool& quicDecryptPool() {
    static ThreadPool pool((std::max<unsigned>)(2, std::thread::hardware_concurrency()));
    return pool;
+6 −13
Changes for test/quic_parallel_decrypt_test.cpp: 6 added lines, 13 removed lines.
Original line number Diff line number Diff line
@@ -188,19 +188,12 @@ static void test_forced_batch_real_decrypt() {
        client.sendStreamData(sid, chunk.data(), chunk.size(), i == N - 1);
    }

    // Assemble a real, valid N-packet batch out of N individually-received
    // datagrams. This sandbox's recvmmsg() only ever returns one datagram
    // per call regardless of how many are actually queued (confirmed via
    // FIONREAD during development: the kernel already has all N queued, but
    // recvmmsg(vlen=64) still returns 1 at a time here) — an environment
    // quirk, not something under this codebase's control, and consistent
    // with this same session's earlier finding that real bulk-transfer
    // benchmarks also never see recvbatch avg/max above 1.0 in this
    // sandbox. Each datagram is copied out of the thread_local scratch
    // buffer immediately (DatagramView is only valid until the next
    // recvBatchViews() call on this thread) into test-owned storage, so the
    // resulting batch is still N genuinely-received, genuinely-encrypted
    // packets — just assembled by the test instead of by a single syscall.
    // Assemble a real, valid N-packet batch out of the received datagrams.
    // Each datagram is copied out of the thread_local scratch buffer
    // immediately (DatagramView is only valid until the next recvBatchViews()
    // call on this thread) into test-owned storage, so the resulting batch
    // is still N genuinely-received, genuinely-encrypted packets — just
    // assembled by the test instead of by a single syscall.
    // processApplicationPacketsBatchParallel() itself has no way to tell
    // the difference: it only ever sees a std::vector<std::pair<...>>.
    //