Repository navigation
Cache cuvidGetDecoderCaps per process - #6560
Conversation
The decoder capabilities do not change, but cuvidGetDecoderCaps is serialized in the driver and was queried for every file, which gets slow when many decoders open files at once. Cache the result per device, codec, chroma format and bit depth, and hold the lock during the query so that decoders that start at once query each configuration only once. Used by NVDECCache::GetDecoder and SelectVideoStream. Signed-off-by: Joaquin Anton Guirao <janton@nvidia.com>
9524d9b to
d34ab22
Compare
There was a problem hiding this comment.
🟢 Approval recommended
The focused change preserves capability checks, correctly synchronizes cache access, and leaves failed queries uncached.
No open issues 🎉
What changed in this PR
This PR reduces repeated NVDEC capability queries when GPU video decoders open files, helping avoid driver contention during concurrent decoding.
Changes:
- Adds a process-wide capability cache keyed by device, codec, chroma format, and bit depth.
- Synchronizes cache access and queries so concurrent requests populate each configuration only once.
- Uses cached capabilities in stream selection and decoder creation while preserving validation and query-failure handling.
| File | Description |
|---|---|
dali/operators/video/frames_decoder_gpu.cc |
Adds the synchronized capability cache and updates both per-file and decoder-creation query sites. |
Review effort: Balanced
[Medium impact] The PR appears safe to merge; the remaining test-coverage suggestion is non-blocking.
|
|
!build |
|
CI MESSAGE: [77048240]: BUILD STARTED |
The cache is mostly read: look it up under a shared lock, and only on a miss take the exclusive lock, check again and query the driver, so that each configuration is still queried once. Signed-off-by: Joaquin Anton Guirao <janton@nvidia.com>
|
!build |
|
CI MESSAGE: [77062151]: BUILD STARTED |
|
CI MESSAGE: [77062151]: BUILD PASSED |
Category:
Other (e.g. Documentation, Tests, Configuration): performance improvement, no functional change.
Description:
FramesDecoderGpuqueries the driver withcuvidGetDecoderCapsevery time it opens a file, and again whenever it needs a new NVDEC decoder:SelectVideoStream(run when the decoder is constructed, i.e. for every file), to check that NVDEC supports the codec;NVDECCache::GetDecoder, when no cached decoder can be reused and a new one has to be created, to check the codec configuration and its size limits.The result depends only on the GPU and on the codec, chroma format and bit depth, so it never changes during the process. The call is serialized in the driver, though. With one decoder that is a small, fixed cost per file. When many decoders open files at the same time, the calls queue up in the driver and each one becomes slow, which stalls decoding on every file switch. This affects every user of
FramesDecoderGpu(fn.experimental.readers.video,fn.experimental.decoders.videoandfn.experimental.inputs.videoon the GPU). It matters most for workloads that switch files often (short clips, smallsequence_length) with several decoders opening files at once, and it gets worse once a reader runs several decoders concurrently, as planned with the decode lanes (#6563, #6564).This PR adds
frame_dec_gpu_impl::GetDecoderCaps, which caches theCUVIDDECODECAPSper process, keyed by the current device, codec, chroma format and bit depth. The lock is held during the driver query as well, so decoders that start at the same time query each configuration only once instead of all missing the cache together. Both call sites above use it. The static helperFramesDecoderGpu::SupportsHevc, which is not called per file (only the tests use it), still calls the driver directly.Split out of #6545.
It is based on
mainand independent of the other PRs. It touchesNVDECCache::GetDecodernext to the lines that #6540 changes, so whichever of the two merges second may need a trivial rebase.Additional information:
Affected modules and functionalities:
dali/operators/video/frames_decoder_gpu.cc:frame_dec_gpu_impl::GetDecoderCaps(static mutex andstd::mapkeyed by device, codec, chroma format and bit depth);NVDECCache::GetDecoderandFramesDecoderGpu::SelectVideoStreamuse it instead of callingcuvidGetDecoderCapsdirectly.Key points relevant for the review:
cudaGetDevice), so multi-GPU processes and GPUs of different generations get their own entries.CUDA_CALLthrows) is not cached; the next call queries again. An unsupported configuration (bIsSupported == 0) is cached like any other result, as it is a property of the hardware.Tests:
frames_decoder_test.cc:FramesDecoderGpuTest.*(e.g.ConstantFrameRate,VariableFrameRateHevc,InMemoryVfrHevcVideo,RawH264,RawH265,DecoderCacheReusedForCroppedVideo), which open many files with H.264, HEVC and MPEG-4 and go through both cached call sites.decoder/test_video.py: GPU tests offn.experimental.readers.videoandfn.experimental.decoders.video.Checklist
Documentation
DALI team only
Requirements
REQ IDs: N/A
JIRA TASK: DALI-4935