mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
perf: zone CPU profiler (PerfLog) + phase-restructured CPU spectrum render
Инструментация (ВРЕМЕННАЯ, не мержить в main): - PerfLog.pas: зонные таймеры, отчёт раз в 5с в stderr (core% = доля ядра), EWSDR_PERF=0 выкл, EWSDR_PERF_FILE=путь — дублировать в файл - Замеры // PERF: сеть (DDC IQ/wideband), Pluto (rx_conv/tx_resamp/tx_fill), DSP (push_iq/fexchange/slices/tx), аудио, UI (тики/draw/paint/gl_swap, разбивка draw_spectrum по фазам) - doc/PERF_PROFILING.md: карта зон, методика, выводы Оптимизация CPU-рендера спектра (по результатам замеров на эфире): диагноз — дорога не пиксельная работа, а чередование raw(ScanLine)/ canvas(QPainter) доступа к битмапу на Qt6 (~6 переходов за кадр, каждый синкает весь битмап; полоса фильтра в тысячи пикселей стоила 4x дороже полного memcpy кадра). DrawSpectrum перестроен в фазы calc->raw->canvas->raw (2 перехода): FillBandRaw вместо Canvas.FillRect, DrawSliceFilterMarkers разделён на raw-полосы + canvas-линии, композиты флагов и альфа-OR в финальной raw-фазе. Кадр 8.3мс -> 6.1мс; spec_bands 1.87мс -> 0.03мс. Альфа-OR проход на Qt6 подтверждён нужным (без него canvas-пиксели теряют альфу и пропадают при блите), сам цикл ~0.08мс — оставлен; тумблер EWSDR_ALPHA_FIX=0 только для экспериментов. Кисть перед AGC-подписями теперь ставится явно (была остаточной после перестройки фаз). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,7 @@ uses
|
||||
WidebandView,
|
||||
StatusBar,
|
||||
PlatformUtils,
|
||||
PerfLog, // ВРЕМЕННО (perf/cpu-profiling): зонные CPU-таймеры
|
||||
WinFirewall,
|
||||
BoardUtils, WisdomBuilder, UISync,
|
||||
FlatEdit, FMRepeater,
|
||||
@@ -3168,7 +3169,10 @@ var
|
||||
PeakTarget, MinTarget: Double;
|
||||
PeakDiff, MinDiff: Double;
|
||||
PeakAlpha, MinAlpha: Double;
|
||||
PerfT0: Int64; // PERF
|
||||
begin
|
||||
PerfT0 := PerfNow; // PERF
|
||||
try
|
||||
if not FController.FRunning then
|
||||
begin
|
||||
if PbSMeterRight <> nil then PbSMeterRight.Invalidate;
|
||||
@@ -3222,6 +3226,9 @@ begin
|
||||
else
|
||||
SetStatusText(5, 'TX idle');
|
||||
end;
|
||||
finally
|
||||
PerfAdd(pzUiMeterTick, PerfT0); // PERF: тик метра целиком (10 Гц)
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.SpectrumTimerTick(Sender: TObject);
|
||||
@@ -3229,7 +3236,10 @@ var
|
||||
NowTick: QWord;
|
||||
ElapsedTick: QWord;
|
||||
I: Integer;
|
||||
PerfT0, PerfTz: Int64; // PERF
|
||||
begin
|
||||
PerfT0 := PerfNow; // PERF
|
||||
try
|
||||
// Синхронизируем размеры если размер панели изменился (после ресайза).
|
||||
// Важно: проверяем только видимые панели — когда спектр скрыт,
|
||||
// PbSpectrum.Height может быть ненулевым при FSpectrumHeight=0,
|
||||
@@ -3302,13 +3312,16 @@ begin
|
||||
// Обновляем оверлей если видим
|
||||
if Assigned(FVfoOverlay) and FVfoOverlay.Visible then
|
||||
begin
|
||||
PerfTz := PerfNow; // PERF
|
||||
FVfoOverlay.UpdateSMeter(FController.FLastSMeter);
|
||||
FVfoOverlay.UpdateVfo(FController.FVfoA);
|
||||
PushVfoOverlayExtState;
|
||||
PositionVfoOverlay;
|
||||
PerfAdd(pzUiVfoOverlay, PerfTz); // PERF: обновление главного VFO-флага
|
||||
end;
|
||||
if Length(FSliceFlags) > 0 then
|
||||
begin
|
||||
PerfTz := PerfNow; // PERF
|
||||
PositionSliceFlags; // держим слайс-флаги на частоте
|
||||
// S-метр слайсов троттлим до ~10 Гц: каждое изменение метра = софтовый
|
||||
// ре-рендер флага (дорого), 60 Гц там не нужно.
|
||||
@@ -3319,6 +3332,7 @@ begin
|
||||
if FSliceFlags[I] <> nil then
|
||||
FSliceFlags[I].UpdateSMeter(FController.SliceSMeter(FSliceFlags[I].SliceId));
|
||||
end;
|
||||
PerfAdd(pzUiSliceFlags, PerfTz); // PERF: позиционирование + S-метры слайс-флагов
|
||||
end;
|
||||
// Панорама и водопад теперь рисуются независимо по факту новых кадров.
|
||||
// Это лучше совпадает с Thetis: маленький FFT даёт новые строки чаще.
|
||||
@@ -3385,7 +3399,14 @@ begin
|
||||
// Исходящее зеркало состояния + спектр/водопад в web — в адаптере (всё из
|
||||
// FController, включая последний кадр пикселей). Сервер сам гейтит по FRunning.
|
||||
if Assigned(FWebAdapter) then
|
||||
begin
|
||||
PerfTz := PerfNow; // PERF
|
||||
FWebAdapter.PushState;
|
||||
PerfAdd(pzUiWebPush, PerfTz); // PERF: web-зеркало состояния + кадры клиентам
|
||||
end;
|
||||
finally
|
||||
PerfAdd(pzUiSpectrumTick, PerfT0); // PERF: тик спектра целиком (кадровый таймер)
|
||||
end;
|
||||
end;
|
||||
|
||||
// ===========================================================================
|
||||
|
||||
Reference in New Issue
Block a user