mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-03 13:54:55 +03:00
Improve Intel stats collection
This commit is contained in:
parent
c35cee2d2f
commit
3835e7649c
@ -261,45 +261,33 @@ async def set_gpu_stats(
|
||||
else:
|
||||
stats["jetson-gpu"] = {"gpu": "", "mem": ""}
|
||||
hwaccel_errors.append(args)
|
||||
elif "qsv" in args:
|
||||
elif "qsv" in args or ("vaapi" in args and not is_vaapi_amd_driver()):
|
||||
if not config.telemetry.stats.intel_gpu_stats:
|
||||
continue
|
||||
|
||||
# intel QSV GPU
|
||||
intel_usage = get_intel_gpu_stats(config.telemetry.stats.intel_gpu_device)
|
||||
|
||||
if intel_usage is not None:
|
||||
stats["intel-qsv"] = intel_usage or {"gpu": "", "mem": ""}
|
||||
else:
|
||||
stats["intel-qsv"] = {"gpu": "", "mem": ""}
|
||||
hwaccel_errors.append(args)
|
||||
elif "vaapi" in args:
|
||||
if is_vaapi_amd_driver():
|
||||
if not config.telemetry.stats.amd_gpu_stats:
|
||||
continue
|
||||
|
||||
# AMD VAAPI GPU
|
||||
amd_usage = get_amd_gpu_stats()
|
||||
|
||||
if amd_usage:
|
||||
stats["amd-vaapi"] = amd_usage
|
||||
else:
|
||||
stats["amd-vaapi"] = {"gpu": "", "mem": ""}
|
||||
hwaccel_errors.append(args)
|
||||
else:
|
||||
if not config.telemetry.stats.intel_gpu_stats:
|
||||
continue
|
||||
|
||||
# intel VAAPI GPU
|
||||
if "intel-gpu" not in stats:
|
||||
# intel GPU (QSV or VAAPI both use the same physical GPU)
|
||||
intel_usage = get_intel_gpu_stats(
|
||||
config.telemetry.stats.intel_gpu_device
|
||||
)
|
||||
|
||||
if intel_usage is not None:
|
||||
stats["intel-vaapi"] = intel_usage or {"gpu": "", "mem": ""}
|
||||
stats["intel-gpu"] = intel_usage or {"gpu": "", "mem": ""}
|
||||
else:
|
||||
stats["intel-vaapi"] = {"gpu": "", "mem": ""}
|
||||
stats["intel-gpu"] = {"gpu": "", "mem": ""}
|
||||
hwaccel_errors.append(args)
|
||||
elif "vaapi" in args:
|
||||
if not config.telemetry.stats.amd_gpu_stats:
|
||||
continue
|
||||
|
||||
# AMD VAAPI GPU
|
||||
amd_usage = get_amd_gpu_stats()
|
||||
|
||||
if amd_usage:
|
||||
stats["amd-vaapi"] = amd_usage
|
||||
else:
|
||||
stats["amd-vaapi"] = {"gpu": "", "mem": ""}
|
||||
hwaccel_errors.append(args)
|
||||
elif "preset-rk" in args:
|
||||
rga_usage = get_rockchip_gpu_stats()
|
||||
|
||||
|
||||
@ -39,8 +39,12 @@ class TestGpuStats(unittest.TestCase):
|
||||
process.stdout = self.intel_results
|
||||
sp.return_value = process
|
||||
intel_stats = get_intel_gpu_stats(False)
|
||||
print(f"the intel stats are {intel_stats}")
|
||||
# rc6 values: 47.844741 and 100.0 → avg 73.92 → gpu = 100 - 73.92 = 26.08%
|
||||
# Render/3D/0: 0.0 and 0.0 → enc = 0.0%
|
||||
# Video/0: 4.533124 and 0.0 → dec = 2.27%
|
||||
assert intel_stats == {
|
||||
"gpu": "1.13%",
|
||||
"gpu": "26.08%",
|
||||
"mem": "-%",
|
||||
"enc": "0.0%",
|
||||
"dec": "2.27%",
|
||||
}
|
||||
|
||||
@ -265,14 +265,30 @@ def get_amd_gpu_stats() -> Optional[dict[str, str]]:
|
||||
|
||||
|
||||
def get_intel_gpu_stats(intel_gpu_device: Optional[str]) -> Optional[dict[str, str]]:
|
||||
"""Get stats using intel_gpu_top."""
|
||||
"""Get stats using intel_gpu_top.
|
||||
|
||||
Returns overall GPU usage derived from rc6 residency (idle time),
|
||||
plus individual engine breakdowns:
|
||||
- enc: Render/3D engine (compute/shader encoder, used by QSV)
|
||||
- dec: Video engines (fixed-function codec, used by VAAPI)
|
||||
"""
|
||||
|
||||
def get_stats_manually(output: str) -> dict[str, str]:
|
||||
"""Find global stats via regex when json fails to parse."""
|
||||
reading = "".join(output)
|
||||
results: dict[str, str] = {}
|
||||
|
||||
# render is used for qsv
|
||||
# rc6 residency for overall GPU usage
|
||||
rc6_match = re.search(r'"rc6":\{"value":([\d.]+)', reading)
|
||||
if rc6_match:
|
||||
rc6_value = float(rc6_match.group(1))
|
||||
results["gpu"] = f"{round(100.0 - rc6_value, 2)}%"
|
||||
else:
|
||||
results["gpu"] = "-%"
|
||||
|
||||
results["mem"] = "-%"
|
||||
|
||||
# Render/3D is the compute/encode engine
|
||||
render = []
|
||||
for result in re.findall(r'"Render/3D/0":{[a-z":\d.,%]+}', reading):
|
||||
packet = json.loads(result[14:])
|
||||
@ -280,11 +296,9 @@ def get_intel_gpu_stats(intel_gpu_device: Optional[str]) -> Optional[dict[str, s
|
||||
render.append(float(single))
|
||||
|
||||
if render:
|
||||
render_avg = sum(render) / len(render)
|
||||
else:
|
||||
render_avg = 1
|
||||
results["enc"] = f"{round(sum(render) / len(render), 2)}%"
|
||||
|
||||
# video is used for vaapi
|
||||
# Video engines are the fixed-function decode engines
|
||||
video = []
|
||||
for result in re.findall(r'"Video/\d":{[a-z":\d.,%]+}', reading):
|
||||
packet = json.loads(result[10:])
|
||||
@ -292,12 +306,8 @@ def get_intel_gpu_stats(intel_gpu_device: Optional[str]) -> Optional[dict[str, s
|
||||
video.append(float(single))
|
||||
|
||||
if video:
|
||||
video_avg = sum(video) / len(video)
|
||||
else:
|
||||
video_avg = 1
|
||||
results["dec"] = f"{round(sum(video) / len(video), 2)}%"
|
||||
|
||||
results["gpu"] = f"{round((video_avg + render_avg) / 2, 2)}%"
|
||||
results["mem"] = "-%"
|
||||
return results
|
||||
|
||||
intel_gpu_top_command = [
|
||||
@ -336,10 +346,16 @@ def get_intel_gpu_stats(intel_gpu_device: Optional[str]) -> Optional[dict[str, s
|
||||
return get_stats_manually(output)
|
||||
|
||||
results: dict[str, str] = {}
|
||||
rc6_values = []
|
||||
render = {"global": []}
|
||||
video = {"global": []}
|
||||
|
||||
for block in data:
|
||||
# rc6 residency: percentage of time GPU is idle
|
||||
rc6 = block.get("rc6", {}).get("value")
|
||||
if rc6 is not None:
|
||||
rc6_values.append(float(rc6))
|
||||
|
||||
global_engine = block.get("engines")
|
||||
|
||||
if global_engine:
|
||||
@ -373,11 +389,22 @@ def get_intel_gpu_stats(intel_gpu_device: Optional[str]) -> Optional[dict[str, s
|
||||
if video_frame is not None:
|
||||
video[key].append(float(video_frame))
|
||||
|
||||
if render["global"] and video["global"]:
|
||||
results["gpu"] = (
|
||||
f"{round(((sum(render['global']) / len(render['global'])) + (sum(video['global']) / len(video['global']))) / 2, 2)}%"
|
||||
# Overall GPU usage from rc6 (idle) residency
|
||||
if rc6_values:
|
||||
rc6_avg = sum(rc6_values) / len(rc6_values)
|
||||
results["gpu"] = f"{round(100.0 - rc6_avg, 2)}%"
|
||||
|
||||
results["mem"] = "-%"
|
||||
|
||||
# Encoder: Render/3D engine (compute/shader encode)
|
||||
if render["global"]:
|
||||
results["enc"] = (
|
||||
f"{round(sum(render['global']) / len(render['global']), 2)}%"
|
||||
)
|
||||
results["mem"] = "-%"
|
||||
|
||||
# Decoder: Video engine (fixed-function codec)
|
||||
if video["global"]:
|
||||
results["dec"] = f"{round(sum(video['global']) / len(video['global']), 2)}%"
|
||||
|
||||
if len(render.keys()) > 1:
|
||||
results["clients"] = {}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user