Vai ir veiktspējas atšķirība starp atmiņas piešķiršanu izpildes laikā un sastādīšanas laiku C programmēšanas valodā?


Atbilde 1:

Jā, tā kā kompilators un saišu redaktors ņem vērā arī statiskos atmiņas piešķīrumus, izliekot iegūto izpildāmo, jo visi pieprasītie izmēri ir iepriekš zināmi un šādā veidā iedalītā atmiņa paliek rezervēta visu procesa laiku.

Tādā veidā “statiski atvēlot atmiņu” kļūst par “piemērotu caurumu atstāšanu” izpildāmajā failā (visi sabrūk inicializētās atmiņas “datu” sadaļā un neinicializētās atmiņas “rss” sadaļā), tādējādi kļūstot par procesa daļu izpildāmā attēlošana atmiņā ar programmas slodzi bez ievērojamiem pieskaitāmiem izpildes laikā.

Salīdziniet to ar dinamisko sadalījumu no kaudzes izpildlaikā, kur ir sadalītājs (ti, malloc (), calloc () utt.), Kuram ir jāseko līdzi brīvajiem apgabaliem, pašlaik rezervētajiem apgabaliem, un katru reizi jānoskaidro daži atmiņai tiek pieprasīta piemērota brīva zona, mēģinot apturēt ārēju sadrumstalotību.

Jūs jautājāt: Vai ir veiktspējas atšķirība starp atmiņas piešķiršanu izpildes laikā un sastādīšanas laiku C programmēšanas valodā?


Atbilde 2:

Jā, acīmredzot ātrāk to izdarīt sastādīšanas laikā, bet tas ir atkarīgs. Būtībā tas, ko jūs darāt, apkopojot laiku, ir iepriekšdatoru aprēķināšana tam, kas tiktu darīts izpildlaikā.

Tas ir sava veida izplatīts zema līmeņa sistēmās, kurās malloc tiek savādāk sarauts. Malloc tērē resursus un ciklus, tāpēc, ja plānojat to sastādīšanas laikā, varat no tā izvairīties.

Es šeit vispārinu, un dažreiz jūs esat to iestrēdzis. Izpētot malloc savstarpējo sadarbību, jūs sāksit izprast dažas briesmas. Tas, cik bieži veicat atmiņas piešķiršanas operācijas zvanus, ietekmē arī gaisvadu pieskārienu.


Atbilde 3:

Jā, apkopot laika piešķīrumus, pamatojoties uz blokiem, tie netiek pārvaldīti. Runtime piešķiršana tiek piešķirta no kaudzes, un parasti tā tiek pietiekami izsekota, lai vēlāk atbrīvotu. (Es saku vispārīgi, jo ir daudz dažādu kaudzes sadales algoritmu, kas ir izstrādāti, lai atbalstītu dažādus sadales lietošanas modeļus)

tātad

apkopo laiku:

statisks char bigstring [5000];

tas ir izdarīts vienu reizi, nav reālas izsekošanas tam, kas piešķirts, tas ir tikai daļa no iepriekš iedalītajiem datu blokiem, kad tiek palaista lietotne (pamatā es domāju, ka steks pirms steka rāmja).

izpildlaiks:

char * pBigString = malloc (5000);

iesaistiet vietējo kaudzi (C izpildlaika kaudze), lai arī kaudzes ir optimizētas, tās var kļūt sadrumstalotas un atkarībā no ieviešanas aizņem nelielu laiku vai nu bez maksas, vai arī pa labi.

Apkopotā laika sadalījuma lielumu mainīt nevar, savukārt izpildlaika piešķīrumi var būt jebkura lieluma. Jūs varat pārstrādāt savus blokus un saglabāt rādītāju līdz pēdējam, ko piešķīrāt, ja jūs uztrauc piešķīruma veiktspēja (pieņemot, ka tie visi ir vienāda lieluma).


Atbilde 4:

Faktiskā atmiņas pieeja ir tieši tāda pati lasīšanai un rakstīšanai. Bet atmiņas piešķiršana izpildes laikā prasa laiku. (un var neizdoties!).

Atmiņa ir atmiņa. Tas ir daudz ātrāk nekā disku lasīšana un rakstīšana, USB pārsūtīšana utt. Galvenā atmiņa ir ledāja ziņā lēna, salīdzinot ar CPU kešatmiņu, kā arī ar video atmiņu videokartē.

Tātad C kompilatori veic labu darbu, optimizējot kodu, lai tas darbotos kešatmiņā, atkarībā no prasībām un koda rakstītāja aparatūras zināšanām. Tātad apkopotais kods darbojas ļoti ātri, un statiski piešķirtā krātuve tiks ielādēta arī kešatmiņā, ja tā ir pareiza lieluma.

Darbības laikā iedalītā atmiņa (dinamiskā atmiņa, kaudzes atmiņa) tiks piešķirta tajā pašā galvenajā atmiņā kā jebkura cita, taču kompilators to nevar ļoti labi optimizēt. Var būt 50/50, vai jūsu kaudzes atmiņas atdalīšana prasīs dažas milisekundes vai dažus simtus milisekundes un vai tā ietilps visu CPU kešatmiņā, un vai tā būs jaukā sakoptā atmiņas lapā vai sadalīta vairākās atmiņas lapās.

Tātad jums ir jāaprēķina vidējais laiks, kas pavadīts funkcijā, kas atvēl atmiņu izpildes laikā lielam skaitam darbību ar dažādām datu ielādēm, lai norādītu, cik ātra būs funkcija vai cik lēna tā var būt, ja lietas tajā laikā nav optimālas.

Mūsdienu galddatori, serveri, tālruņi utt. Darbojas lielās slodzēs, jo programmas aizpilda resursus un CPU laiku. Lai jūsu programma uzrunātu operētājsistēmu lielās slodzēs un pieprasītu atmiņas pakalpojumu piešķiršanu, kā arī atmiņas atbrīvošanu, būs vajadzīgs laiks, un ir ārkārtīgi grūti precīzi noteikt, cik ilgs laiks ir nepieciešams, lai varētu sākt rakstīt uz to. atmiņa.

Operētājsistēmām ir virkne triku, kas jāizmanto, lai paātrinātu to, kur viņi var - nokopēt uzrakstot, kur tiek pieprasīta un “piešķirta” atmiņa programmai, bet tā nemaz netiek dota, kamēr programma nemēģina lasīt vai rakstīt tā, virtuālā atmiņa diska failos, lai notīrītu aktīvo programmu gaidīšanas programmu atmiņas reģionus (apmainītos ar failiem) utt.

Tas viss tiek darīts parasti zem līmeņa, kurā programmētājs to redz vai viņam ir kontrole. Līdz šim lēnākā atmiņas daļa ir I / O no ierīcēm. Tāpēc parasti vislabākais paātrinājums, ja jums ir I / O vājās vietas ar ierīcēm, ir ierīces kartēšana ar atmiņā kartētu failu ar buferi un I / O izkraušana atsevišķā pavedienā.

Dažas operētājsistēmas pat nodrošina jums ar atmiņu kartētu failu sistēmu, kuru jūs varat izmantot tāpat kā parastu failu vai direktoriju! (Linux ir direktorija / var / run / shm ("shared mem"), kur to var izdarīt ļoti ātri.)