Mediastreamer2 VoIP programmas izpēte. 12. daļa

Raksta materiāls ņemts no mana zen kanāls.

Mediastreamer2 VoIP programmas izpēte. 12. daļa

Pagātnē raksts, es apsolÄ«ju izskatÄ«t jautājumu par svārsta slodzes novērtÄ“Å”anu un veidiem, kā cÄ«nÄ«ties ar pārmērÄ«gu skaitļoÅ”anas slodzi multivides straumētājā. Bet es nolēmu, ka loÄ£iskāk bÅ«tu aplÅ«kot ar datu kustÄ«bu saistÄ«tos amatniecÄ«bas filtru atkļūdoÅ”anas jautājumus un tikai pēc tam apsvērt veiktspējas optimizācijas jautājumus.

Amatniecības filtru atkļūdoŔana

Pēc tam, kad iepriekŔējā rakstā apskatÄ«jām datu pārvietoÅ”anas mehānismu mediju straumētājā, bÅ«tu loÄ£iski runāt par tajā slēptajām briesmām. Viena no ā€œdatu plÅ«smasā€ principa iezÄ«mēm ir tāda, ka atmiņa no kaudzes tiek pieŔķirta filtros, kas atrodas datu plÅ«smas avotā, un atmiņu atbrÄ«vo un atgriež kaudzē ar filtriem, kas atrodas plÅ«smas beigās. ceļŔ. Turklāt jaunu datu radÄ«Å”ana un iznÄ«cināŔana var notikt kaut kur pa vidu. Parasti atmiņas atbrÄ«voÅ”anu veic cits filtrs, nevis tas, kas izveidoja datu bloku.

No caurspÄ«dÄ«gas atmiņas uzraudzÄ«bas viedokļa bÅ«tu saprātÄ«gi, ja filtrs, saņemot ievades bloku, pēc apstrādes, atbrÄ«vojot atmiņu, to nekavējoties iznÄ«cinātu un izvadÄ«tu jaunizveidotu bloku ar izvaddatiem. Šādā gadÄ«jumā bÅ«tu viegli izsekot atmiņas noplÅ«dei filtrā - ja analizators konstatē noplÅ«di filtrā, tad nākamais filtrs pareizi neiznÄ«cina ienākoÅ”os blokus un tajā ir kļūda. Bet no augstas veiktspējas uzturÄ“Å”anas viedokļa Ŕī pieeja darbam ar datu blokiem nav produktÄ«va - tas noved pie liela skaita operāciju, lai pieŔķirtu/atbrÄ«votu atmiņu datu blokiem bez noderÄ«gas izvades.

Å Ä« iemesla dēļ multivides straumētāju filtri, lai nepalēninātu datu apstrādi, izmanto funkcijas, kas, kopējot ziņojumus, izveido vienkārÅ”as kopijas (par tām mēs runājām iepriekŔējā rakstā). Å Ä«s funkcijas tikai izveido jaunu ziņojuma galvenes gadÄ«jumu, ā€œpievienojotā€ tai datu bloku no kopējamā ā€œvecāā€ ziņojuma. Rezultātā vienam datu blokam tiek pievienotas divas galvenes un tiek palielināts atsauces skaitÄ«tājs datu blokā. Bet tas izskatÄ«sies pēc diviem ziņojumiem. Ar Ŕādu ā€œsocializētuā€ datu bloku ziņojumu var bÅ«t vairāk, piemēram, MS_TEE filtrs uzreiz Ä£enerē duci Ŕādu gaiÅ”u kopiju, sadalot tās pa saviem izvadiem. Ja visi ķēdes filtri darbojas pareizi, lÄ«dz konveijera beigām Å”im atsauces skaitÄ«tājam vajadzētu sasniegt nulli un tiks izsaukta atmiņas atbrÄ«voÅ”anas funkcija: ms_free(). Ja zvans nenotiek, tad Ŕī atmiņas daļa vairs netiks atgriezta kaudzē, t.i. tas "noplÅ«dÄ«s". Vieglo kopiju izmantoÅ”anas cena ir zaudēta iespēja viegli noteikt (kā tas bÅ«tu parasto kopiju gadÄ«jumā), kuram grafika filtram noplÅ«st atmiņa.

Tā kā multivides straumētāju izstrādātāji ir atbildÄ«gi par atmiņas noplÅ«des atraÅ”anu vietējos filtros, visticamāk, jums tās nebÅ«s jāatkļūdo. Bet ar savu amatniecÄ«bas filtru jÅ«s esat savas laimes sienāzis, un laiks, ko pavadÄ«sit, meklējot noplÅ«des savā kodā, bÅ«s atkarÄ«gs no jÅ«su precizitātes. Lai samazinātu atkļūdoÅ”anas laiku, izstrādājot filtrus, ir jāņem vērā noplūžu noteikÅ”anas metodes. Turklāt var gadÄ«ties, ka noplÅ«de izpaudÄ«sies tikai tad, kad filtrs tiks uzlikts reālā sistēmā, kur ā€œaizdomās turamoā€ skaits var bÅ«t milzÄ«gs un atkļūdoÅ”anas laiks ierobežots.

Kā izpaužas atmiņas noplūde?

Ir loÄ£iski pieņemt, ka programmas izvadē tops parādÄ«s pieaugoÅ”o lietojumprogrammas aizņemtās atmiņas procentuālo daudzumu.

Ārējā izpausme būs tāda, ka kādā brīdī sistēma sāks lēnām reaģēt uz peles kustību un lēnām pārzīmēs ekrānu. Iespējams, ka sistēmas žurnāls pieaugs, aizņemot vietu jūsu cietajā diskā. Šajā gadījumā jūsu lietojumprogramma sāks darboties dīvaini, neatbildēs uz komandām, nevarēs atvērt failu utt.

Lai noteiktu noplÅ«des raÅ”anos, mēs izmantosim atmiņas analizatoru (turpmāk ā€“ analizators). Tas varētu bÅ«t Valgrinda (labi raksts par to) vai iebÅ«vēts kompilatorā GCC Atmiņas sanitizer vai kaut kas cits. Ja analizators parāda, ka kādā no grafika filtriem ir noplÅ«de, tas nozÄ«mē, ka ir pienācis laiks izmantot kādu no tālāk aprakstÄ«tajām metodēm.

Trīs priežu metode

Kā minēts iepriekÅ”, ja ir atmiņas noplÅ«de, analizators norādÄ«s uz filtru, kas pieprasÄ«ja atmiņas pieŔķirÅ”anu no kaudzes. Bet tas nenorādÄ«s filtru, kas ā€œaizmirsaā€ to atgriezt, kas patiesÄ«bā ir vaininieks. Tādējādi analizators var tikai apstiprināt mÅ«su bailes, bet ne norādÄ«t to sakni.

Lai noskaidrotu ā€œsliktāā€ filtra atraÅ”anās vietu grafikā, varat samazināt grafiku lÄ«dz minimālajam mezglu skaitam, kuros analizators joprojām konstatē noplÅ«di, un lokalizēt problemātisko filtru atlikuÅ”ajās trÄ«s priedēs.

Bet var gadīties, ka, samazinot filtru skaitu grafikā, jūs izjauksiet normālu filtru mijiedarbības gaitu ar citiem jūsu sistēmas elementiem un noplūde vairs neparādīsies. Šajā gadījumā jums būs jāstrādā ar pilna izmēra grafiku un jāizmanto tālāk aprakstītā pieeja.

Bīdāmā izolatora metode

Prezentācijas vienkārŔības labad mēs izmantosim grafiku, kas sastāv no vienas filtru ķēdes. Viņa ir parādÄ«ta attēlā.

Mediastreamer2 VoIP programmas izpēte. 12. daļa

Parasts grafiks, kurā lÄ«dzās gataviem mediju straumētāju filtriem tiek izmantoti četri četru dažādu veidu craft filtri F1...F4, kurus esi izveidojis jau sen un par to pareizÄ«bu neÅ”aubies. Tomēr pieņemsim, ka vairākiem no tiem ir atmiņas noplÅ«des. Kad mēs palaižam savu programmu analizatora pārraudzÄ«bai, no tā ziņojuma mēs uzzinām, ka noteikts filtrs pieprasÄ«ja noteiktu atmiņas apjomu un neatgrieza to kaudzē N reižu skaitu. Varat viegli uzminēt, ka bÅ«s saite uz MS_VOID_SOURCE tipa iekŔējām filtra funkcijām. Viņa uzdevums ir izņemt atmiņu no kaudzes. Citiem filtriem tas ir jāatgriež tur. Tie. mēs noteiksim noplÅ«des faktu.

Lai noteiktu, kurā cauruļvada posmā notikusi bezdarbÄ«ba, kas izraisÄ«ja atmiņas noplÅ«di, tiek ierosināts ieviest papildu filtru, kas vienkārÅ”i pārslēdz ziņojumus no ievades uz izvadi, bet tajā paŔā laikā izveido ievades ziņojuma kopiju, kas nav gaiÅ”a. , bet gan parastu ā€œsmagoā€, pēc tam pilnÄ«bā izdzÄ“Å” pie ieejas saņemto ziņu. Mēs Ŕādu filtru sauksim par izolatoru. Mēs uzskatām, ka, tā kā filtrs ir vienkārÅ”s, tajā nav noplÅ«des. Un vēl viena pozitÄ«va Ä«paŔība - ja mēs to pievienosim jebkurā grafikā, tas nekādā veidā neietekmēs ķēdes darbÄ«bu. Mēs attēlosim filtru-izolatoru apļa formā ar dubultu ķēdi.

Mēs ieslēdzam izolatoru tūlīt pēc voidsource filtra:
Mediastreamer2 VoIP programmas izpēte. 12. daļa

Mēs atkal palaižam programmu ar analizatoru, un mēs redzam, ka Å”oreiz analizators vainos izolatoru. Galu galā tieÅ”i viņŔ tagad izveido datu blokus, kurus pēc tam pazaudē nezināms neuzmanÄ«gs filtrs (vai filtri). Nākamais solis ir pārvietot izolatoru pa ķēdi pa labi, par vienu filtru, un sākt analÄ«zi no jauna. Tātad, soli pa solim pārvietojot izolatoru pa labi, mēs iegÅ«sim situāciju, ka nākamajā analizatora ziņojumā samazināsies ā€œnoplÅ«duÅ”oā€ atmiņas bloku skaits. Tas nozÄ«mē, ka Å”ajā posmā izolators atradās ķēdē tÅ«lÄ«t pēc problēmas filtra. Ja bija tikai viens ā€œsliktsā€ filtrs, tad noplÅ«de pazudÄ«s pavisam. Tādējādi mēs lokalizējām problemātisko filtru (vai vienu no vairākiem). Pēc filtra ā€œnofiksÄ“Å”anasā€ mēs varam turpināt virzÄ«t izolatoru pa ķēdi pa labi, lÄ«dz pilnÄ«bā uzvarēsim atmiņas noplÅ«des.

Izolatora filtra ievieŔana

Izolatora ievieŔana izskatās tāpat kā parasts filtrs. Galvenes fails:

/* Š¤Š°Š¹Š» 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

Pats filtrs:

/* Š¤Š°Š¹Š» 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)

Atmiņas pārvaldÄ«bas funkciju aizstāŔanas metode

Smalkākai izpētei mediju straumētājs nodroÅ”ina iespēju atmiņas piekļuves funkcijas aizstāt ar savējām, kas papildus galvenajam darbam ierakstÄ«s ā€œKas, kur un kāpēcā€. Tiek aizstātas trÄ«s funkcijas. Tas tiek darÄ«ts Ŕādi:

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

Å Ä« funkcija palÄ«dz gadÄ«jumos, kad analizators tik ļoti palēnina filtru darbÄ«bu, ka tiek traucēta tās sistēmas darbÄ«ba, kurā ir iebÅ«vēta mÅ«su ķēde. Šādā situācijā jums ir jāatsakās no analizatora un jāizmanto funkciju aizstāŔana darbam ar atmiņu.

Mēs esam apsvēruÅ”i darbÄ«bu algoritmu vienkārÅ”am grafikam, kas nesatur zarus. Taču Å”o pieeju var pielietot arÄ« citos gadÄ«jumos, protams, sarežģītāk, taču ideja paliek nemainÄ«ga.

Nākamajā rakstā mēs apskatÄ«sim jautājumu par slodžu slodzes novērtÄ“Å”anu un veidus, kā cÄ«nÄ«ties pret pārmērÄ«gu skaitļoÅ”anas slodzi multivides straumētājā.

Avots: www.habr.com

Pievieno komentāru