Skip to main content
Glama
by 8b-is
PPS_CONTEXT_SWITCH_WISDOM.md7.31 kB
# The Ultimate Network Truth: PPS and Context Switches 🧠 ## The Router Reality Nobody Talks About Routers have a dirty secret: **They're limited by PACKETS per second, not bytes!** ### Typical Router Limits: - **Home router**: 50K-150K PPS - **Small business**: 500K-1M PPS - **Enterprise**: 10M+ PPS - **Your 50-byte spam**: EATING ALL OF IT! ## The Game Developer's Enlightenment 🎮 ### The Crime Scene: ```c // BAD: Every 16ms (60 FPS) send_packet(player_position); // 50 bytes send_packet(player_rotation); // 30 bytes send_packet(player_animation); // 20 bytes send_packet(audio_data); // 100 bytes send_packet(game_state); // 40 bytes // 5 packets × 60fps × 100 players = 30,000 PPS! // Router: "I'm dying here!" ``` ### The Enlightened Way: ```c // GOOD: Combined packet struct GameUpdate { uint16_t player_id; float pos[3]; // 12 bytes uint16_t rotation; // 2 bytes (quantized) uint8_t animation_id; // 1 byte uint8_t opus_audio[64]; // Opus is efficient! uint8_t game_flags; // 1 byte } __attribute__((packed)); // 1 packet × 60fps × 100 players = 6,000 PPS // Router: "Now we're talking!" ``` ## The Context Switch Massacre 🔄 ### What Really Happens (Per Packet): ``` 1. NIC raises interrupt 2. CPU stops what it's doing 3. Context switch to kernel 4. Process packet headers 5. Context switch to network stack 6. Copy to user space 7. Context switch to game thread 8. Process 50 bytes 9. Resume previous work Time wasted: ~10-50 microseconds Actual processing: 0.1 microseconds Efficiency: 0.2% 😱 ``` ### The Pull vs Push Revolution ❌ **Bob Checking Messages (Polling)**: ```c while (true) { if (check_messages()) { // Every 20ms process(); } // CPU: "Am I a joke to you?" } ``` ✅ **Hey Bob, Check Your Messages (Event-Driven)**: ```c register_callback(on_message_received); // CPU: "Finally, I can do real work!" // When message arrives, NIC uses DMA, one interrupt ``` ## The AI Inference Connection 🤖 This is GENIUS - you've connected networking to AI compute! ### Wasted Cycles = Lost Inference: ``` Traditional approach: - 30,000 interrupts/second - 30,000 context switches - CPU spending 30% time handling tiny packets - AI model: "Why am I getting 70% of expected performance?" Smart approach: - 6,000 interrupts/second - Batched processing - CPU spending 5% on networking - AI model: "NOW I can think properly!" ``` ## Real-World Game Optimization ### Quake's Network Model (Carmack's Wisdom): ```c // Combined update packet struct { uint32_t frame_num; uint8_t player_count; struct { vec3_t position; uint16_t angles[3]; // Quantized uint8_t weapon; uint8_t animation; } players[MAX_VISIBLE]; // Events, sounds, etc. } update_packet; ``` ### Modern Game with Opus + Position: ```c struct AudioPositionalUpdate { // Opus audio frame (super efficient) uint8_t opus_data[120]; // 20ms @ 48kbps // Positional data (quantized) uint16_t x, y, z; // 6 bytes vs 12 for floats uint8_t yaw; // 256 directions enough uint8_t pitch; // Look angle // Game state bits uint8_t flags; // Firing, jumping, etc. } __attribute__((packed)); // 129 bytes total // Send 20 times/second instead of 60 // Include 3 frames of audio per packet // Result: 95% reduction in PPS! ``` ## Bill Burr on Context Switches 🎤 "You know what a context switch is? It's like this: You're making a sandwich. Phone rings. You answer it. It's Bob asking if you got his message. You check. No message. You hang up. Back to sandwich. Phone rings. It's Bob asking if you checked. You just f***ing checked! Hang up. Back to sandwich. Phone rings... THAT'S WHAT YOU'RE DOING TO THE CPU! Let the CPU make its goddamn sandwich! When Bob actually HAS a message, THEN interrupt! And for the love of all that's holy, if Bob has 5 things to say, say them in ONE CALL!" ## The Activity-Based Revolution ### Traditional (Wasteful): ```python # Every frame, every player for player in players: send_position(player) # Even if not moving send_animation(player) # Even if idle send_audio(player) # Even if silent ``` ### Activity-Based (Smart): ```python # Only send what changed if player.moved: updates.add_position(player) if player.audio_active: updates.add_audio(player) if len(updates) > 1000 or time_since_last > 50ms: send_combined_packet(updates) ``` ## The Router's Perspective 📡 ``` Bad Router Day: "100,000 PPS of 50-byte packets" "I have a 10Gbps link but I'm dying at 40Mbps" "It's not the bandwidth, it's the PACKETS!" Good Router Day: "10,000 PPS of 1400-byte packets" "140Mbps of actual data" "CPU at 10% instead of 90%" "I can finally do QoS properly!" ``` ## Core Utilization Paradise 🖥️ ### Before Optimization: ``` Core 0: [████████░░] 80% - Handling interrupts Core 1: [████████░░] 80% - Context switching Core 2: [████░░░░░░] 40% - Actual game logic Core 3: [██░░░░░░░░] 20% - AI inference ``` ### After Optimization: ``` Core 0: [██░░░░░░░░] 20% - Network (batched) Core 1: [████████░░] 80% - Game logic Core 2: [████████░░] 80% - Physics Core 3: [█████████░] 90% - AI inference ``` ## The Metrics That Matter ### Not This: - Bandwidth: 100Mbps ✓ - Latency: 10ms ✓ - Packet Loss: 0.1% ✓ - Game: Unplayable ❌ ### But This: - PPS: Within router limits ✓ - Context switches: Minimized ✓ - CPU available for game: 85% ✓ - Game: Smooth as butter ✓ ## Implementation: The Smart Game Protocol ```c // Every 50ms, not every 16ms void send_game_update() { GamePacket packet = {0}; // Header packet.timestamp = get_time(); packet.packet_type = COMBINED_UPDATE; // Add all updates int offset = 0; // Positions (only for moved entities) offset += pack_positions(&packet.data[offset], moved_entities); // Audio (Opus compressed, multiple frames) offset += pack_audio(&packet.data[offset], audio_buffer, 3); // 3 frames // Events (compressed bitfield) offset += pack_events(&packet.data[offset]); // Send when full or timeout if (offset > 1200 || time_elapsed > 50) { udp_send(packet, offset); reset_buffers(); } } ``` ## The Final Wisdom **For Games**: - Combine position + audio + state - Use activity-based updates - Respect PPS limits - Batch, batch, batch! **For Routers**: - Fewer packets = happy router - Happy router = lower latency - Lower latency = happy gamers **For CPUs**: - Fewer interrupts = more compute - More compute = better AI - Better AI = smarter NPCs **For Penguins**: - Efficient networking = less heat - Less heat = more ice - More ice = happy penguins 🐧 --- *"The best packet is a full packet. The best interrupt is no interrupt. The best context switch is the one that never happens."* - Zen of Network Gaming *"If your game sends 50-byte packets, you're not a game developer, you're a router assassin."* - Bill Burr's GDC Talk

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/8b-is/smart-tree'

If you have feedback or need assistance with the MCP directory API, please join our Discord server