Arsitektur Concurrency pada Vulkan Video
Ekosistem Vulkan Video API (ekstensi VK_KHR_video_queue, VK_KHR_video_decode_queue) memungkinkan decoding hardware langsung via compute context lintas platform. Namun, implementasi pada lingkungan worker terdistribusi menghadapi batasan fisik: jumlah hardware decode queue (VkQueueFamilyProperties dengan flag VK_QUEUE_VIDEO_DECODE_BIT_KHR) pada satu physical device sangat terbatas, umumnya hanya 1 hingga 2 engine independen per GPU.
Ketika beberapa proses worker berebut instansiasi VkDevice dan alokasi video session (VkVideoSessionKHR) secara paralel melampaui kapasitas driver, driver akan melempar VK_ERROR_OUT_OF_DEVICE_MEMORY atau memicu segmentation fault di user-space driver. Solusinya memerlukan koordinasi eksternal untuk mengelola akses resource GPU secara deterministik.
Manajemen Akses Hardware dengan Distributed Semaphore
Untuk mencegah resource exhaustion tanpa membatasi skalabilitas node secara statis, alokasi context dikontrol via distributed counting semaphore pada Redis. Semaphore ini merefleksikan jumlah engine decoding hardware aktual pada node GPU target.
-- Lua Script: acquire_vulkan_slot.lua
-- KEYS[1]: resource_key (contoh: "gpu:0:decode_slots")
-- ARGV[1]: worker_id
-- ARGV[2]: max_slots
-- ARGV[3]: ttl_seconds
local current = redis.call("SCARD", KEYS[1])
if current < tonumber(ARGV[2]) then
redis.call("SADD", KEYS[1], ARGV[1])
redis.call("EXPIRE", KEYS[1], tonumber(ARGV[3]))
return 1
end
return 0Script Lua memastikan operasi penambahan slot berjalan atomik di Redis runtime:
-- Lua Script: release_vulkan_slot.lua
-- KEYS[1]: resource_key
-- ARGV[1]: worker_id
redis.call("SREM", KEYS[1], ARGV[1])
return 1Worker wajib memperbarui TTL key melalui thread heartbeat terpisah selama pipeline vkQueueSubmit berjalan. Jika worker mati mendadak, lease slot akan kedaluwarsa otomatis dan membebaskan antrean.
Desain Shared Queue Berbasis Ring Buffer
Pemrosesan frame terkompresi membutuhkan zero-copy memory alignment untuk efisiensi transfer PCIe ke staging buffer Vulkan. Job queue diimplementasikan menggunakan circular ring buffer pada shared memory (shm) antarmuka IPC, dipadu Redis stream sebagai dispatcher kontrol metadata.
#pragma pack(push, 1)
struct FrameSlot {
uint32_t frame_index;
uint32_t payload_size;
uint8_t nal_unit_type;
uint8_t is_keyframe;
uint64_t pts;
uint8_t data[1024 * 512]; // 512 KB inline buffer per packet
};
struct RingBufferQueue {
uint32_t capacity;
_Atomic uint32_t head;
_Atomic uint32_t tail;
struct FrameSlot slots[64];
};
#pragma pack(pop)Struktur memory-mapped di atas diakses secara lock-free menggunakan atomic operations (memory_order_acquire dan memory_order_release). Ingestion process bertindak sebagai single producer pada indeks tail, sedangkan worker Vulkan mengonsumsi packet pada indeks head sebelum dipetakan ke VkBuffer melalui vkMapMemory.
Pipeline Vulkan Video Decoding
Alur eksekusi decode di worker mengikuti sequence berikut:
- Acquire Lock: Eksekusi
acquire_vulkan_slot.luahingga mendapatkan slot decode. - Queue Initialization: Query queue family via
vkGetPhysicalDeviceQueueFamilyProperties2, ambil handleVkQueueyang mendukung decoding. - Session Allocation: Alokasi
VkVideoSessionKHRdengan profil codec yang cocok (H.264/HEVC/AV1) beserta memory backing bind viavkBindVideoSessionMemoryKHR. - Ring Buffer Ingestion: Salin payload terkompresi dari shared memory ke bound memory
VkBuffer. - Command Execution: Panggil
vkCmdBeginVideoCodingKHR,vkCmdDecodeVideoKHR, danvkCmdEndVideoCodingKHR. - Submission: Kirim batch ke GPU via
vkQueueSubmitdengan CPU fence (VkFence) untuk sinkronisasi. - Release Lock: Eksekusi
release_vulkan_slot.luadan reset struct state.
Penanganan Crash dan State Recovery
Worker crash saat memegang status decode dapat meninggalkan state hardware zombie atau frame terputus. Recovery dirancang bertingkat:
- Heartbeat Dead-man Switch: Jika heartbeat Redis gagal diperbarui selama 5 detik, watchdog process menganggap worker failed dan mengembalikan slot via script cleanup.
- Vulkan Device Loss Mitigation: Jika terjadi error
VK_ERROR_DEVICE_LOSTakibat bitstream corrupt, worker tidak boleh mencoba recovery inline padaVkDeviceyang sama. Worker harus memanggilvkDestroyDevice, menghancurkan poolVkCommandPool, dan menginstansiasi ulang logical device secara bersih. - Dangling Shm Cleanup: Ring buffer mencatat PID worker yang aktif. Jika PID mati di tengah konsumsi, tail/head pointer dikembalikan ke sequence keyframe IDR terakhir untuk mencegah error decoding antar-frame (P/B-frame referencing error).
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!