Mediastreamer2 VoIP қозғалтқышын зерттеу. 12 бөлім

Мақала материалы менің сайтымнан алынды zen арнасы.

Mediastreamer2 VoIP қозғалтқышын зерттеу. 12 бөлім

Өткенде мақала, Мен медиа стримерлердегі шамадан тыс есептеу жүктемесімен күресу жолдарын және тикер жүктемесін бағалау мәселесін қарастыруға уәде бердім. Бірақ мен деректер қозғалысына қатысты қолөнер сүзгілерін жөндеу мәселелерін қамту және содан кейін өнімділікті оңтайландыру мәселелерін қарастыру қисындырақ болады деп шештім.

Қолөнер сүзгілерін түзету

Алдыңғы мақалада медиа стримерлердегі деректер қозғалысының механизмін қарастырғаннан кейін, онда жасырылған қауіптер туралы айту қисынды болар еді. «Деректер ағыны» принципінің ерекшеліктерінің бірі мынада: жадты үйіндіден бөлу деректер ағынының көздерінде орналасқан сүзгілерде жүреді, ал ағын жолының соңында орналасқан сүзгілер қайтарумен жадты әлдеқашан бөледі. үйіндіге. Сонымен қатар, жаңа деректерді құру және олардың жойылуы аралық нүктелердің бір жерінде болуы мүмкін. Жалпы жадты босату деректер блогын жасағаннан басқа сүзгі арқылы жүзеге асырылады.

Жадтың мөлдір мониторингі тұрғысынан сүзгі кіріс блогын алған кезде оны өңдегеннен кейін, жадты босатқаннан кейін дереу жойып, шығыс деректері бар жаңадан жасалған блокты шығысқа қоюы орынды болар еді. Бұл жағдайда сүзгідегі жадтың ағып кетуін оңай байқауға болады — егер анализатор сүзгіде ағып кетуді анықтаса, одан кейінгі сүзгі кіріс блоктарын дұрыс бұзбайды және онда қате бар. Бірақ жоғары өнімділікті сақтау тұрғысынан деректер блоктарымен жұмыс істеудің бұл тәсілі өнімді емес - бұл деректер блоктары үшін ешқандай пайдалы шығынсыз жадты бөлу / босату операцияларының көптігіне әкеледі.

Осы себепті, медиа ағынды сүзгілері деректерді өңдеуді бәсеңдетпеу үшін хабарламаларды көшіру кезінде жеңіл көшірмелерді жасайтын функцияларды пайдаланады (біз олар туралы алдыңғы мақалада айтқан болатынбыз). Бұл функциялар тек көшірілген «ескі» хабарламадан деректер блогын «тіркеу» арқылы хабарлама тақырыбының жаңа көшірмесін жасайды. Нәтижесінде бір деректер блогына екі тақырып қосылады және деректер блогындағы анықтамалық есептегіш ұлғаяды. Бірақ бұл екі хабарлама сияқты болады. Мұндай «жалпы» деректер блогы бар хабарламалар көбірек болуы мүмкін, мысалы, MS_TEE сүзгісі бірден ондай жеңіл көшірмелерді жасайды, оларды шығыстары арасында таратады. Тізбектегі барлық сүзгілер дұрыс жұмыс істесе, конвейердің соңында бұл сілтеме саны нөлге жетуі керек және жадты босату функциясы шақырылады: ms_free(). Егер қоңырау орын алмаса, онда бұл жад бөлігі бұдан былай үйіндіге қайтарылмайды, яғни. ол «ағып кетеді». Жеңіл көшірмелерді пайдалану құны - бұл жадтың қай графикалық сүзгіде ағып жатқанын оңай анықтау мүмкіндігінің жоғалуы (тұрақты көшірмелерді пайдаланған кездегідей).

«Туған» сүзгілердегі жадтың ағып кетуін табу жауапкершілігі медиа ағынды жасаушыларға жүктелетіндіктен, оларды жөндеудің қажеті жоқ. Бірақ қолөнер сүзгісі арқылы сіз өзіңіздің бақытыңыздың шегірткесісіз және кодыңыздағы ағып кетулерді іздеуге жұмсайтын уақытыңыз дәлдігіңізге байланысты болады. Түзету уақытын қысқарту үшін сүзгілерді жобалау кезінде ағып кетуді локализациялау әдістерін қарастыруымыз керек. Сонымен қатар, ағып кету «күдіктілердің» саны өте көп болуы мүмкін және жөндеу уақыты шектеулі болатын нақты жүйеде сүзгіні қолданғанда ғана көрінуі мүмкін.

Жадтың ағуы қалай көрінеді?

Бағдарламаның шығысында деп болжау қисынды TOP қолданбаңыз алатын жадтың өсу пайызын көрсетеді.

Сыртқы көрініс белгілі бір уақытта жүйе тінтуірдің қозғалысына баяу әрекет етеді, экранды баяу қайта салады. Сондай-ақ, жүйелік журналдың қатты дискідегі бос орынды жеп өсуі мүмкін. Бұл жағдайда сіздің қолданбаңыз оғаш әрекет ете бастайды, командаларға жауап бермейді, файлды аша алмайды және т.б.

Ағып кету фактісін анықтау үшін біз жад анализаторын (бұдан әрі - анализатор) қолданамыз. Бұл болуы мүмкін Вальгринд (жақсы мақала ол туралы) немесе компиляторға салынған gcc Жад тазартқыш немесе басқа нәрсе. Егер анализатор ағып кету графикалық сүзгілердің бірінде орын алатындығын көрсетсе, бұл төменде сипатталған әдістердің бірін қолдану уақыты келді дегенді білдіреді.

Үш қарағай әдісі

Жоғарыда айтылғандай, жад ағып кеткен жағдайда, анализатор үймеден жадты бөлуді сұраған сүзгіні көрсетеді. Бірақ ол оны қайтаруды «ұмытып кеткен» сүзгіні көрсетпейді, бұл шын мәнінде кінәлі. Осылайша, анализатор біздің қорқынышымызды растай алады, бірақ олардың түбірін көрсетпейді.

Графиктегі «нашар» сүзгінің орнын анықтау үшін сызбаны анализатор әлі де ағып кетуді анықтайтын түйіндердің ең аз санына дейін азайту арқылы өтуге және қалған үш қарағайдағы проблемалық сүзгіні табуға болады.

Бірақ бағандағы сүзгілердің санын азайту арқылы сіз сүзгілер мен жүйеңіздің басқа элементтері арасындағы қалыпты әрекеттесу процесін бұзасыз және ағып кету енді пайда болмайды. Бұл жағдайда сізге толық өлшемді графикпен жұмыс істеуге және төменде сипатталған тәсілді қолдануға тура келеді.

Жылжымалы оқшаулағыш әдісі

Презентацияның қарапайымдылығы үшін біз сүзгілердің бір тізбегінен тұратын графикті қолданамыз. Ол суретте көрсетілген.

Mediastreamer2 VoIP қозғалтқышын зерттеу. 12 бөлім

Кәдімгі график, онда дайын мультимедиа ағынды сүзгілерімен қатар, төрт қолөнер сүзгілері F1…F4 пайдаланылады, сіз бұрыннан жасаған және олардың дұрыстығына күмәнданбайтын төрт түрлі түрі. Дегенмен, олардың бірнешеуінде жады ағып кетті делік. Біздің анализаторды қадағалау бағдарламамызды іске қосқан кезде біз оның есебінен белгілі бір сүзгі жадтың белгілі бір көлемін сұрағанын және оны N рет үймеге қайтармағанын білеміз. MS_VOID_SOURCE түрінің ішкі сүзгі функцияларына сілтеме болатынын болжау оңай. Оның міндеті - үйіндіден жад алу. Басқа сүзгілер оны сол жерге қайтаруы керек. Анау. біз ағып кетуді табамыз.

Жадтың ағып кетуіне әкелген құбырдың қай бөлігінде әрекетсіздік орын алғанын анықтау үшін хабарламаларды кірістен шығысқа жай ғана ауыстыратын, бірақ сонымен бірге кірістің жеңіл емес көшірмесін жасайтын қосымша сүзгіні енгізу ұсынылады. хабарламаны кәдімгі «ауыр» көшірмеге айналдырыңыз, содан кейін кіруге келген хабарлама толығымен жойылады. Мұндай сүзгіні оқшаулағыш деп атаймыз. Сүзгі қарапайым болғандықтан, оның ағып кетуін болдырмайды деп ойлаймыз. Және тағы бір оң қасиет - егер біз оны графиктің кез келген жеріне қоссақ, онда бұл тізбектің жұмысына ешқандай әсер етпейді. Біз оқшаулағыш сүзгіні қос контуры бар шеңбер ретінде бейнелейміз.

Бос көз сүзгісінен кейін оқшаулағышты қосыңыз:
Mediastreamer2 VoIP қозғалтқышын зерттеу. 12 бөлім

Бағдарламаны анализатормен қайтадан іске қосамыз, бұл жолы анализатор кінәні изоляторға жүктейтінін көреміз. Өйткені, ол қазір белгісіз ұқыпсыз сүзгі (немесе сүзгілер) арқылы жоғалатын деректер блоктарын жасайды. Келесі қадам - ​​оқшаулағышты тізбек бойымен оңға, бір сүзгіге жылжыту және талдауды қайтадан бастау. Сонымен, оқшаулағышты оңға қарай жылжыта отырып, келесі анализатор есебінде «ағып кеткен» жад блоктарының саны азайған жағдайды аламыз. Бұл дегеніміз, бұл қадамда оқшаулағыш проблемалық сүзгіден кейін бірден тізбекте аяқталды. Егер бір ғана «нашар» сүзгі болса, онда ағып кету мүлдем жоғалады. Осылайша, біз проблемалық сүзгіні (немесе бірнеше біреуін) локализацияладық. Сүзгіні «түзетіп» болған соң, жадтың ағып кетуі толығымен жойылғанша оқшаулағышты тізбек бойымен оңға жылжытуды жалғастыра аламыз.

Оқшаулағыш сүзгіні енгізу

Оқшаулағышты іске асыру кәдімгі сүзгіге ұқсайды. Тақырып файлы:

/* Файл 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

Сүзгінің өзі:

/* Файл 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)

Жадты басқару функцияларын ауыстыру әдісі

Неғұрлым нәзік зерттеу үшін медиа стримері жадқа қол жеткізу функцияларын өзіңіздікімен ауыстыру мүмкіндігін береді, ол негізгі жұмысқа қосымша «Кім, қайда және неге» жазады. Үш функция ауыстырылуда. Бұл келесі жолмен жүзеге асырылады:

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);

Бұл мүмкіндік анализатор сүзгілерді баяулататыны сонша, біздің схема салынған жүйенің жұмысы бұзылған жағдайда құтқаруға келеді. Мұндай жағдайда анализатордан бас тартып, есте сақтау функцияларын ауыстыруды қолдануға тура келеді.

Біз тармақтары жоқ қарапайым график үшін әрекеттер алгоритмін қарастырдық. Бірақ бұл тәсілді басқа жағдайларда қолдануға болады, әрине, асқынумен, бірақ идея өзгеріссіз қалады.

Келесі мақалада біз тикер жүктемесін бағалау мәселесін және медиа стримерлердегі шамадан тыс есептеу жүктемесін қалай шешуге болатынын қарастырамыз.

Ақпарат көзі: www.habr.com

пікір қалдыру