Mediastreamer2 VoIP mühərriki araşdırılır. 12-ci hissə

Məqalənin materialı məndən götürülmüşdür zen kanalı.

Mediastreamer2 VoIP mühərriki araşdırılır. 12-ci hissə

Sonda məqalə, mən ticker yükünün qiymətləndirilməsi məsələsini və media streamerdə həddindən artıq hesablama yükü ilə mübarizə yollarını nəzərdən keçirməyə söz verdim. Ancaq qərara gəldim ki, məlumatların hərəkəti ilə əlaqəli sənətkarlıq filtrlərinin düzəldilməsi məsələlərini əhatə etmək daha məntiqli olardı və yalnız bundan sonra performansın optimallaşdırılması məsələlərini nəzərdən keçirin.

Sənət filtrlərinin sazlanması

Əvvəlki məqalədə media strimerində məlumatların hərəkət mexanizmini araşdırdıqdan sonra orada gizlənən təhlükələrdən danışmaq məntiqli olardı. “Məlumat axını” prinsipinin xüsusiyyətlərindən biri ondan ibarətdir ki, yaddaşın yığından ayrılması məlumat axınının mənbələrində yerləşən filtrlərdə baş verir və axın yolunun sonunda yerləşən filtrlər artıq yaddaşı qaytarmaqla bölüşdürür. yığına. Bundan əlavə, yeni məlumatların yaradılması və onların məhv edilməsi ara nöqtələrdə bir yerdə baş verə bilər. Ümumiyyətlə, yaddaşın buraxılması məlumat blokunu yaradan filtrdən başqa bir filtr tərəfindən həyata keçirilir.

Yaddaşın şəffaf monitorinqi nöqteyi-nəzərindən filtrin giriş blokunu qəbul edərkən onu emal etdikdən, yaddaş boşaldıqdan sonra dərhal məhv etməsi və çıxışa çıxış məlumatları ilə yeni yaradılmış blok qoyması məqsədəuyğun olardı. Bu halda, filtrdə yaddaş sızması asanlıqla izlənilə bilərdi - analizator filtrdə sızma aşkar edərsə, onu izləyən filtr daxil olan blokları düzgün məhv etmir və onda xəta var. Lakin yüksək performansın qorunması baxımından məlumat blokları ilə işləməyə bu yanaşma məhsuldar deyil - bu, heç bir faydalı işlənmədən məlumat blokları üçün yaddaşın ayrılması / boşaldılması üçün çoxlu əməliyyatlara səbəb olur.

Bu səbəbdən, media streamer filtrləri məlumatların işlənməsini ləngitməmək üçün mesajları köçürərkən yüngül surətlər yaradan funksiyalardan istifadə edir (bunlar haqqında əvvəlki məqalədə danışmışdıq). Bu funksiyalar yalnız kopyalanan "köhnə" mesajdan məlumat blokunu ona "qoşmaqla" mesaj başlığının yeni nüsxəsini yaradır. Nəticədə bir verilənlər blokuna iki başlıq əlavə olunur və verilənlər blokunda istinad sayğacı artırılır. Ancaq iki mesaj kimi görünəcək. Belə "ictimai" məlumat bloku ilə daha çox mesaj ola bilər, məsələn, MS_TEE filtri bir anda on belə işıq nüsxəsi yaradır və onları çıxışları arasında paylayır. Zəncirdəki bütün filtrlər düzgün işləyirsə, boru kəmərinin sonunda bu istinad sayı sıfıra çatmalı və yaddaşın boşaldılması funksiyası çağırılacaqdır: ms_free(). Zəng baş verməzsə, bu yaddaş parçası artıq yığına qaytarılmayacaq, yəni. o "sızır". Yüngül nüsxələrdən istifadənin dəyəri yaddaşın hansı qrafik filtrində sızdığını (adi nüsxələrdən istifadə vəziyyətində olduğu kimi) asanlıqla müəyyən etmək qabiliyyətinin itirilməsidir.

"Doğma" filtrlərdə yaddaş sızmalarının tapılması məsuliyyəti media yayımçısının tərtibatçılarına aid olduğundan, çox güman ki, onları sazlamaq məcburiyyətində olmayacaqsınız. Ancaq sənətkarlıq filtrinizlə özünüz öz xoşbəxtliyiniz çəyirtkəsiniz və kodunuzda sızmaların axtarışına sərf etdiyiniz vaxt dəqiqliyinizdən asılı olacaq. Sazlama vaxtınızı azaltmaq üçün filtrlər hazırlayarkən sızmaların lokallaşdırılması üsullarına baxmalıyıq. Bundan əlavə, baş verə bilər ki, sızma yalnız "şübhəlilərin" sayının çox ola biləcəyi və səhvlərin aradan qaldırılması üçün vaxtın məhdud olduğu real sistemdə filtr tətbiq edildikdə özünü göstərəcək.

Yaddaş sızması özünü necə göstərir?

Proqramın çıxışında olduğunu güman etmək məntiqlidir yuxarı tətbiqinizin tutduğu yaddaşın artan faizini göstərəcək.

Xarici təzahür ondan ibarət olacaq ki, bir nöqtədə sistem yavaş-yavaş ekranı yenidən çəkərək siçanın hərəkətinə yavaş reaksiya verəcəkdir. Sistem jurnalının sabit diskdə yer tutaraq böyüməsi də mümkündür. Bu zaman tətbiqiniz qəribə davranmağa başlayacaq, əmrlərə cavab verməyəcək, faylı aça bilməyəcək və s.

Sızma faktını müəyyən etmək üçün yaddaş analizatorundan (bundan sonra analizator adlandırılacaq) istifadə edəcəyik. Ola bilər valgrind (yaxşı məqalə haqqında) və ya kompilyatorda quraşdırılmışdır gcc Yaddaş Təmizləyicisi və ya başqa bir şey. Əgər analizator sızmanın qrafik filtrlərindən birində baş verdiyini göstərirsə, deməli, aşağıda təsvir olunan üsullardan birini tətbiq etməyin vaxtı çatıb.

Üç Şam üsulu

Yuxarıda qeyd edildiyi kimi, yaddaş sızması halında, analizator yığından yaddaşın ayrılmasını tələb edən filtrə işarə edəcəkdir. Ancaq onu qaytarmağı "unudan" filtrə işarə etməyəcək, əslində günahkardır. Beləliklə, analizator yalnız qorxularımızı təsdiqləyə bilər, lakin onların kökünü göstərə bilməz.

Qrafikdəki "pis" filtrin yerini öyrənmək üçün qrafiki analizatorun hələ də sızma aşkar etdiyi minimum qovşaq sayına endirməklə gedə və qalan üç şamda problemli filtri tapa bilərsiniz.

Ancaq ola bilər ki, sütundakı filtrlərin sayını azaltmaqla siz filtrlər və sisteminizin digər elementləri arasında normal qarşılıqlı əlaqəni pozacaqsınız və sızma artıq görünməyəcək. Bu halda, siz tam ölçülü bir qrafiklə işləməli və aşağıda təsvir olunan yanaşmadan istifadə etməli olacaqsınız.

Sürüşən izolyator üsulu

Təqdimatın sadəliyi üçün bir filtr zəncirindən ibarət olan qrafikdən istifadə edəcəyik. O, şəkildə göstərilib.

Mediastreamer2 VoIP mühərriki araşdırılır. 12-ci hissə

Hazır media yayımlayıcı filtrləri ilə yanaşı, dörd sənətkarlıq filtri F1…F4 istifadə edilən, çoxdan hazırladığınız dörd müxtəlif növ və onların düzgünlüyünə şübhə etmədiyiniz adi qrafik. Lakin tutaq ki, onlardan bir neçəsində yaddaş sızması var. Analizatora nəzarət proqramımızı işləyərkən biz onun hesabatından öyrənirik ki, müəyyən filtr müəyyən miqdarda yaddaş tələb edib və onu N dəfə yığına qaytarmayıb. MS_VOID_SOURCE tipli daxili filtr funksiyalarına istinad olacağını təxmin etmək asandır. Onun vəzifəsi yaddaşı yığından götürməkdir. Digər filtrlər onu ora qaytarmalıdır. Bunlar. sızıntısını tapacağıq.

Boru kəmərinin hansı hissəsində yaddaş sızmasına səbəb olan hərəkətsizliyin baş verdiyini müəyyən etmək üçün mesajları sadəcə olaraq girişdən çıxışa keçirən, lakin eyni zamanda girişin işıqsız surətini yaradan əlavə filtrin tətbiqi təklif edilir. mesajı normal "ağır" nüsxəyə köçürün, sonra girişə gələn mesajı tamamilə silin. Belə bir filtri izolyator adlandıracağıq. İnanırıq ki, filtr sadə olduğundan içindəki sızma istisna olunur. Və daha bir müsbət xüsusiyyət - onu qrafikimizdə hər hansı bir yerə əlavə etsək, bu, dövrənin işinə heç bir şəkildə təsir etməyəcək. İzolyator filtrini ikiqat konturlu bir dairə kimi təsvir edəcəyik.

Boşluq filtrindən dərhal sonra izolyatoru işə salın:
Mediastreamer2 VoIP mühərriki araşdırılır. 12-ci hissə

Proqramı yenidən analizatorla işlədirik və görürük ki, bu dəfə analizator günahı izolyatorun üzərinə atacaq. Axı, indi naməlum laqeyd filtr (və ya filtrlər) tərəfindən itirilən məlumat bloklarını yaradan odur. Növbəti addım izolyatoru zəncir boyunca sağa, bir filtrlə sürüşdürmək və yenidən analizə başlamaqdır. Beləliklə, addım-addım, izolyatoru sağa doğru hərəkət etdirərək, növbəti analizator hesabatında "sızan" yaddaş bloklarının sayının azaldığı bir vəziyyət əldə edirik. Bu o deməkdir ki, bu mərhələdə izolyator problemli filtrdən dərhal sonra zəncirə daxil olub. Yalnız bir "pis" filtr varsa, sızma tamamilə yox olacaq. Beləliklə, problemli filtri (və ya bir neçədən birini) lokallaşdırdıq. Filtri "sabitləşdirərək" yaddaş sızması tamamilə aradan qaldırılana qədər izolyatoru zəncir boyunca sağa hərəkət etdirməyə davam edə bilərik.

İzolyator filtrinin tətbiqi

İzolyatorun tətbiqi adi filtr kimi görünür. Başlıq faylı:

/* Файл iso_filter.h  Описание изолирующего фильтра. */

#ifndef iso_filter_h
#define iso_filter_h

/* Задаем идентификатор фильтра. */
#include <mediastreamer2/msfilter.h>

#define MY_ISO_FILTER_ID 1024

extern MSFilterDesc iso_filter_desc;

#endif

Filtr özü:

/* Файл iso_filter.c  Описание изолирующего фильтра. */

#include "iso_filter.h"

    static void
iso_init (MSFilter * f)
{
}
    static void
iso_uninit (MSFilter * f)
{
}

    static void
iso_process (MSFilter * f)
{
    mblk_t *im;

    while ((im = ms_queue_get (f->inputs[0])) != NULL)
    {
        ms_queue_put (f->outputs[0], copymsg (im));
        freemsg (im);
    }
}

static MSFilterMethod iso_methods[] = {
    {0, NULL}
};

MSFilterDesc iso_filter_desc = {
    MY_ISO_FILTER_ID,
    "iso_filter",
    "A filter that reads from input and copy to its output.",
    MS_FILTER_OTHER,
    NULL,
    1,
    1,
    iso_init,
    NULL,
    iso_process,
    NULL,
    iso_uninit,
    iso_methods
};

MS_FILTER_DESC_EXPORT (iso_desc)

Yaddaş idarəetmə funksiyalarının dəyişdirilməsi üsulu

Daha incə araşdırmalar üçün media strimeri yaddaşa giriş funksiyalarını öz funksiyalarınızla əvəz etmək imkanı verir ki, bu da əsas işə əlavə olaraq “Kim, harada və niyə” qeyd edəcək. Üç funksiya dəyişdirilir. Bu aşağıdakı şəkildə edilir:

OrtpMemoryFunctions reserv;
OrtpMemoryFunctions my;

reserv.malloc_fun = ortp_malloc;
reserv.realloc_fun = ortp_realloc;
reserv.free_fun = ortp_free;

my.malloc_fun = &my_malloc;
my.realloc_fun = &my_realloc;
my.free_fun = &my_free;

ortp_set_memory_functions(&my);

Bu xüsusiyyət, analizatorun filtrləri o qədər yavaşlatdığı və dövrəmizin qurulduğu sistemin işləməsinin pozulduğu hallarda xilasetmə üçün gəlir. Belə bir vəziyyətdə analizatordan imtina etməli və yaddaş funksiyalarının əvəz edilməsindən istifadə etməlisiniz.

Budaqları olmayan sadə bir qrafik üçün hərəkətlər alqoritmini nəzərdən keçirdik. Amma bu yanaşma digər hallara da tətbiq oluna bilər, əlbəttə ki, fəsadla, lakin ideya eyni qalır.

Növbəti məqalədə biz ticker yükünün qiymətləndirilməsi məsələsinə və media streamerdə həddindən artıq hesablama yükü ilə necə məşğul olacağımıza baxacağıq.

Mənbə: www.habr.com

Добавить комментарий