Ar yra našumo skirtumų tarp atminties paskirstymo vykdymo metu ir kompiliavimo laiko C programavimo kalba?


Atsakymas 1:

Taip, kadangi kompiliatorius ir nuorodų redaktorius taip pat atsižvelgia į statinį atminties paskirstymą, kai išdėstomas gautas vykdomasis failas, nes visi reikalaujami dydžiai yra žinomi iš anksto, o tokiu būdu paskirta atmintis lieka rezervuota visam proceso laikotarpiui.

Tokiu būdu „statiškai paskirstant atmintį“ reikia „palikti tinkamas skylutes“ vykdomojoje programoje (visa tai sugriuvo inicializuotos atminties „duomenų“ skyriuje ir neinicializuotos atminties „rss“ skyriuje), taigi tampa proceso dalimi. vykdomosios programos atvaizdavimas esant programos apkrovai be pastebimų pridėtinių dalių vykdymo metu.

Palyginkite tai su dinaminiu paskirstymu iš krūvos vykdymo metu, kai yra skirstytuvas (ty malloc (), calloc () ir kt.), Kuris turi sekti šiuo metu laisvas zonas, šiuo metu rezervuotas zonas ir kiekvieną kartą sužinoti bandant sulaikyti išorinį susiskaidymą, atmintyje prašoma tinkamos laisvos vietos.

Jūs paklausėte: Ar yra našumo skirtumų tarp atminties paskirstymo vykdymo metu ir kompiliavimo laiko C programavimo kalba?


Atsakymas 2:

Taip, akivaizdu, kad tai greičiau padaryti sudarymo metu, bet tai priklauso. Iš esmės tai, ką darote sudarydami laiką, yra iš anksto apskaičiuoti, kas būtų padaryta vykdant laiką.

Tai yra įprasta žemo lygio sistemose, kur malloc yra tarsi įbrėžtas. „Malloc“ eikvoja išteklius ir ciklus, taigi, jei planuojate tai rengimo metu, išvengsite šios pridėtinės vertės.

Aš čia apibendrinu, o kartais ir tavo įstrigimas. Pažvelgę ​​į „malloc“ sąveiką, pradėsite suprasti kai kuriuos pavojus. Tai, kaip dažnai skambinate atminties paskirstymo operacijomis, taip pat turės įtakos pridėtinėms vertėms.


Atsakymas 3:

Taip, sudaryti laiko paskirstymai yra pagrįsti bloku, o ne valdomi. Klaida paskirstoma iš krūvos ir paprastai yra pakankamai stebima, kad vėliau būtų galima ją išlaisvinti. (Aš sakau paprastai, kadangi yra daugybė skirtingų krūvos paskirstymo algoritmų, skirtų palankiems skirtingiems paskirstymo naudojimo modeliams)

taigi

sudaryti laiką:

statinė char bigstring [5000];

ji padaryta vieną kartą, nėra realaus sekimo, kas paskirta, tai tik dalis iš anksto paskirstytų duomenų bloko, kai programa paleidžiama (iš esmės pabaiga yra kamino prieš kamino rėmą, manau).

vykdymo laikas:

char * pBigString = malloc (5000);

įtraukti vietinę krūvą (C runtime krūva), nors krūvos yra optimizuotos, jos gali suskaidyti ir užtrukti šiek tiek laiko tiek laisvoje, tiek netinkamoje programoje, atsižvelgiant į įgyvendinimą.

Negalite pakeisti sudaryto laiko paskirstymo dydžio, tuo tarpu veikimo laiko paskirstymas gali būti bet koks, kokio jums patinka. Galite perdirbti blokus ir išlaikyti žymiklį iki paskutinio, kurį skyrėte, jei jums rūpi paskirstymo našumas (darant prielaidą, kad jie visi yra vienodo dydžio).


Atsakymas 4:

Faktinė prieiga prie atminties yra vienoda skaitymo ir rašymo galimybėms. Bet atminties paskirstymas vykdymo metu užima daug laiko. (ir gali nepavykti!).

Atmintis yra atmintis. Tai daug greičiau, nei nuskaito ir rašo diskas, perkelia USB ir tt. Pagrindinė atmintis ledynmečiai yra lėta, palyginti su centrinio procesoriaus laikinoji atmintis, taip pat su vaizdo atmintimi, esančia vaizdo plokštėje.

Taigi, C kompiliatoriai, gerai atsižvelgdami į reikalavimus ir kodo rašytojo technines žinias, optimizuoja kodo veikimą talpykloje. Taigi sudarytas kodas veikia labai greitai, o statiškai paskirta saugykla taip pat bus įkelta į talpyklą, jei ji bus tinkamo dydžio.

Vykdymo metu paskirta atmintis (dinaminė atmintis, krūvos atmintis) bus paskirta toje pačioje pagrindinėje atmintyje kaip ir bet kuri kita, tačiau kompiliatorius to negali iš anksto optimizuoti. Taigi gali būti 50/50, ar jūsų daugybės atminties paskirstymas užtruks keletą milisekundžių ar kelis šimtus milisekundžių, ir ar visa tai tilps CPU talpykloje, ar ji bus tvarkingos atminties puslapyje, ar paskirstyta keliuose atminties puslapiuose.

Taigi, jūs turite apskaičiuoti laiką, praleistą funkcijoje, kuri paskirsto atmintį vykdymo metu, kai vykdoma daugybė darbų su įvairiomis duomenų apkrovomis, kad būtų galima pasakyti, kokia greita bus funkcija ar kokia lėta ji gali būti, jei tuo metu viskas nėra optimalu.

Šiuolaikiniai staliniai kompiuteriai, serveriai, telefonai ir kt. Veikia sunkiai, nes programos kaupia išteklius ir procesoriaus laiką. Norint, kad jūsų programa pasiektų operacinę sistemą esant dideliam krūviui, pareikalauti atminties paslaugų paskirstymo ir taip pat atlaisvinti atmintį, užtruks šiek tiek laiko, ir be galo sunku įvertinti, kiek laiko reikia, kol galėsite pradėti rašyti tam. atmintis.

Operacinės sistemos turi daugybę gudrybių, kurias naudojant galima pagreitinti ten, kur jos gali - kopijuoti rašydamos, kur atmintis yra prašoma ir „suteikiama“ programai, bet iš tikrųjų nėra suteikiama tol, kol programa nemėgina skaityti ar rašyti ji, virtualioji atmintis disko rinkmenose, kad būtų galima išvalyti laisvųjų programų atminties sritis, skirtas aktyvioms naudoti (sukeisti failus) ir kt.

Visa tai paprastai atliekama žemiau lygio, kai programuotojas tai mato ar turi valdymą. Lėtiausia atminties dalis yra I / O iš įrenginių. Taigi paprastai geriausias paspartinimas, kurį turite su įrenginiais turinčiomis I / O kliūtis, yra prietaiso susiejimas su atmintyje pažymėtu failu su buferiu ir I / O iškrovimas į atskirą sriegį.

Kai kurios OS net suteikia jums atmintyje susietą failų sistemą, kurią jau galite naudoti kaip įprastą failą ar katalogą! („Linux“ yra katalogas / var / run / shm („shared mem“), kuriame galite tai padaryti labai greitai.)