/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Effektiv C
Fra : Jakob Møbjerg Nielse~


Dato : 08-12-03 17:33

Hej

Er der nogen der kender noget litteratur (helst på nettet), om hvor
meget det koster at lave systemkald (mere specifikt, hvad der er syrest
af write og malloc/free)?

Endnu mere specifikt:

Det drejer sig om forskellen på at allokere og frigøre X bytes 1 gang
eller write X/2 bytes 2 gange

--
Jakob Møbjerg Nielsen | "Nine-tenths of the universe is the
jakob@dataloger.dk | knowledge of the position and direction
http://www.jakobnielsen.dk/ | of everything in the other tenth."
| -- Terry Pratchett, Thief of Time



 
 
Bertel Brander (08-12-2003)
Kommentar
Fra : Bertel Brander


Dato : 08-12-03 20:17

Jakob Møbjerg Nielsen wrote:
> Hej
>
> Er der nogen der kender noget litteratur (helst på nettet), om hvor
> meget det koster at lave systemkald (mere specifikt, hvad der er syrest
> af write og malloc/free)?
>
> Endnu mere specifikt:
>
> Det drejer sig om forskellen på at allokere og frigøre X bytes 1 gang
> eller write X/2 bytes 2 gange
>

Jeg kender ikke noget litteratur om emnet, men til dit konkrete
spørgsmål:

Det er meget svært at forudsige hvad der er hurtigst. Det afhænger bl.a.
af om din blok er 1Mbyte eller 1GByte, hvilken platform (kompiler, os,
HW) programmet skal køre på.

Normalt vil jeg mene at det er hurtigst at skrive det hele på en gang
fordi RAM er hurtigere end diske, men hvis din blok data er så stor
at den ikke kan være i RAM på en gang, skal dit OS til at gemme dele
af den midlertidigt på disken og det er normalt meget langsomt.

I praksis vil jeg prøve at skrive det hele på en gang, hvis det tager
for lang tid ville jeg prøve at gøre det i mindre stykker.

/b


Jakob Møbjerg Nielse~ (08-12-2003)
Kommentar
Fra : Jakob Møbjerg Nielse~


Dato : 08-12-03 20:40

Bertel Brander wrote:
> Det er meget svært at forudsige hvad der er hurtigst. Det afhænger
> bl.a. af om din blok er 1Mbyte eller 1GByte, hvilken platform
> (kompiler, os, HW) programmet skal køre på.

Størrelsen af dataene kan svinge (sjældent), men det kommer typisk til
at ligge i den lave ende (<1MB). Dette er dog 100% afhængigt af brugen.

Kompiler, OS og HW kan også variere, men lige nu er der tale om GCC,
eCos og i386 (og evt. et ARM9 eval. board, hvis bare det ville virke
.

> Normalt vil jeg mene at det er hurtigst at skrive det hele på en gang
> fordi RAM er hurtigere end diske,

Jeg skulle måske sige at der skrives til en socket. Det er den samme
mængde data der vil blive skrevet til den under alle omstændigheder.

> men hvis din blok data er så stor
> at den ikke kan være i RAM på en gang, skal dit OS til at gemme dele
> af den midlertidigt på disken og det er normalt meget langsomt.

Der er ingen disk i systemet

> I praksis vil jeg prøve at skrive det hele på en gang, hvis det tager
> for lang tid ville jeg prøve at gøre det i mindre stykker.

Jeg ser lige at jeg ikke ligefrem har udtrykt mig superklart:

Efter malloc() skal det hele write's på een gang, så scenarierne vil
typisk være:

for (i = 0; i < X; i++) {
malloc();
}
write();
free();

eller

for (i = 0; i < X/2; i++) {
write();
write();
}


--
Jakob Møbjerg Nielsen | "Nine-tenths of the universe is the
jakob@dataloger.dk | knowledge of the position and direction
http://www.jakobnielsen.dk/ | of everything in the other tenth."
| -- Terry Pratchett, Thief of Time



Mogens Hansen (08-12-2003)
Kommentar
Fra : Mogens Hansen


Dato : 08-12-03 20:11


"Jakob Møbjerg Nielsen" <jakob@dataloger.dk> wrote:

[8<8<8<]
> Jeg skulle måske sige at der skrives til en socket. Det er den samme
> mængde data der vil blive skrevet til den under alle omstændigheder.

For overvejelser og målinger af performance i forbindelse med
netværkprogrammering, så findes der er lang række artikler fra Douglass C.
Schmidt (http://siesta.cs.wustl.edu/~schmidt/).

Så vidt jeg husker er det en væsentlig ting for performance at man ikke
kopierer for mange gange mellem buffere.


[8<8<8<]
> for (i = 0; i < X; i++) {
> malloc();
> }
> write();
> free();

Mange malloc og een free ?


>
> eller
>
> for (i = 0; i < X/2; i++) {
> write();
> write();
> }

Svarer det til det foregående ?

Det er lidt svært at forstå dit problem ud fra din beskrivelse.

Venlig hilsen

Mogens Hansen



Jakob Møbjerg Nielse~ (08-12-2003)
Kommentar
Fra : Jakob Møbjerg Nielse~


Dato : 08-12-03 21:47

Mogens Hansen wrote:
> Mange malloc og een free ?

Ja.

>> for (i = 0; i < X/2; i++) {
>> write();
>> write();
>> }
>
> Svarer det til det foregående ?

Resultatet vil være det samme. Spørgsmålet går på, om det er bedst at
allokere hukommelse til alt der skal sendes, på een gang, eller om det
er bedre at kalde write() adskillige gange. Jeg kan sætte nogle tal på:

Eksempel 1:
malloc() bliver kaldt 20 gange, og write() bliver kaldt en gang (og
strcat() bliver kaldt 40 gange, men det tror jeg ikke betyder noget).

Eksempel 2:
malloc() bliver ikke kaldt, men write() bliver kaldt 40 gange.

Jeg ved det ikke stemmer helt overens med hvad jeg tidligere har
skrevet, men det er ovenstående to eksempler der gælder... den samlede
mængde data der sendes til write() er den samme i begge tilfælde.

> Det er lidt svært at forstå dit problem ud fra din beskrivelse.

Mit problem er at jeg ikke ved om det malloc() koster mere end write().
Der skal under alle omstændigheder laves et context switch til kernen
(og det koster jo også), men hvis nu det tager 3 gange så lang tid at
allokere 5000 bytes 20 gange og skrive det til en socket, som det gør at
skrive 2500 bytes til en socket 40 gange, så vil det ikke være smart at
bruge den øverste metode (som jeg umiddelbart tror er den mest
effektive).

--
Jakob Møbjerg Nielsen | "Nine-tenths of the universe is the
jakob@dataloger.dk | knowledge of the position and direction
http://www.jakobnielsen.dk/ | of everything in the other tenth."
| -- Terry Pratchett, Thief of Time



Bertel Brander (08-12-2003)
Kommentar
Fra : Bertel Brander


Dato : 08-12-03 23:06

Jakob Møbjerg Nielsen wrote:
>
> Eksempel 1:
> malloc() bliver kaldt 20 gange, og write() bliver kaldt en gang (og
> strcat() bliver kaldt 40 gange, men det tror jeg ikke betyder noget).
Hvis du skal strcat'e i enden af en 1Mbyte streng betyder det noget.
>
>
> Mit problem er at jeg ikke ved om det malloc() koster mere end write().
> Der skal under alle omstændigheder laves et context switch til kernen
Hvorfor skal der laves context switch til kernen? malloc() medfører
normalt ikke context switch. En write til socket vil/kan medføre et
context switch.

Det tager normalt ikke ret lang tid at allokere hukommelse, men på en
ARM9 kan 1Mbyte være meget.
Ulempen ved at kalde malloc() er også at du skal kopiere en extra gang,
og du ved måske ikke på forhånd hvor meget hukomelse du får brug for,
derfor kan du måske være nødt til at kopiere data flere gange.

Ville det simpleste ikke være at overføre data til socket'en for hver
data pakke som du modtager?

/b


Jakob Møbjerg Nielse~ (08-12-2003)
Kommentar
Fra : Jakob Møbjerg Nielse~


Dato : 08-12-03 23:28

Bertel Brander wrote:
> Hvis du skal strcat'e i enden af en 1Mbyte streng betyder det noget.

Hvorfor det? Skal strcat() først løbe hele den første streng igennem?

> Hvorfor skal der laves context switch til kernen? malloc() medfører
> normalt ikke context switch.

En applikation har vel ikke lov til bare at tilgå de hukommelsesområder
den vil (på *NIX)? Det vil jo være en enorm sikkerhedsrisiko.

> Det tager normalt ikke ret lang tid at allokere hukommelse, men på en
> ARM9 kan 1Mbyte være meget.

Njoo... http://www.cogcomp.com/csb_csb337.htm, med et CSB300 breakout
board. Problemet i denne sammenhæng er, at den i386 vi tester på er en
Pentium 133 m. 128MB RAM. Projektet går ud på om det kan betale sig at
implementere en Web-service på et mindre embedded system.

> Ulempen ved at kalde malloc() er også at du skal kopiere en extra
> gang,

Hvor sker det?

> og du ved måske ikke på forhånd hvor meget hukomelse du får
> brug for, derfor kan du måske være nødt til at kopiere data flere
> gange.

Det er lige præcis mit problem.

> Ville det simpleste ikke være at overføre data til socket'en for hver
> data pakke som du modtager?

Jo, men er det ikke mindre effektivt (mht. CPU'en), end halvt så mange
malloc() kald?

--
Jakob Møbjerg Nielsen | "Nine-tenths of the universe is the
jakob@dataloger.dk | knowledge of the position and direction
http://www.jakobnielsen.dk/ | of everything in the other tenth."
| -- Terry Pratchett, Thief of Time



Bertel Brander (09-12-2003)
Kommentar
Fra : Bertel Brander


Dato : 09-12-03 00:01

Jakob Møbjerg Nielsen wrote:

> Bertel Brander wrote:
>
>>Hvis du skal strcat'e i enden af en 1Mbyte streng betyder det noget.
>
>
> Hvorfor det? Skal strcat() først løbe hele den første streng igennem?
strcat() er nødt til at løbe hele strengen igennem for at finde enden,
dvs. der hvor den skal tilføje den nye streng.
>
>
>>Hvorfor skal der laves context switch til kernen? malloc() medfører
>>normalt ikke context switch.
>
>
> En applikation har vel ikke lov til bare at tilgå de hukommelsesområder
> den vil (på *NIX)? Det vil jo være en enorm sikkerhedsrisiko.
På de ARM'er jeg har arbejdet med, er der ikke memory protection. Alle
threads/processer kan tilgå alt memory. De nyere ARM'er (med nogle
OS'er) kan lave memory protection, jeg ved ikke om det er tilfældet med
din.
Hvis ikke der er memory protection er der vel ingen grund til at lave
context switch?
>
>
>>Ulempen ved at kalde malloc() er også at du skal kopiere en extra
>>gang,
>
>
> Hvor sker det?
>
>
>>og du ved måske ikke på forhånd hvor meget hukomelse du får
>>brug for, derfor kan du måske være nødt til at kopiere data flere
>>gange.
>
>
> Det er lige præcis mit problem.

Som jeg forstår det, modtager du data der skal sendes over en socket.
Hvis du sender dem med det samme, kan du (måske) lade data blive i den
buffer de er i, når du modtager dem, indtil de er sendt.
Hvis du derimod skal gemme flere blokke indtil du har en hel pakke,
er du vel nødt til at allokere en buffer som du kan gemme dem i, indtil
de kan sendes. Det er denne buffer du ikke kender størrelsen på, og som
du dermed skal lade gro indtil du kan sende pakken. For hver blok du
modtager skal du vel kopiere data over i denne buffer og hvis bufferen
indeholder data og den ikke er stor nok, skal de data der er i bufferen
kopieres over i en ny buffer.
>
>
>>Ville det simpleste ikke være at overføre data til socket'en for hver
>>data pakke som du modtager?
>
>
> Jo, men er det ikke mindre effektivt (mht. CPU'en), end halvt så mange
> malloc() kald?
>

Jo, hvis man kun ser på et write() kald i forhold til et malloc() kald,
men hvis man ser på hele systemet er det ikke sikkert at det forholder
sig sådan.

/b


Jakob Møbjerg Nielse~ (09-12-2003)
Kommentar
Fra : Jakob Møbjerg Nielse~


Dato : 09-12-03 10:48

Bertel Brander wrote:
> Som jeg forstår det, modtager du data der skal sendes over en socket.

Jeps. Jeg modtager data fra en socket, kører det gennem en *lille*
HTTP-server, videre igennem Expat (en XML parser), processerer input'et,
genererer et svar og sender det tilbage gennem samme socket.

> Hvis du sender dem med det samme, kan du (måske) lade data blive i den
> buffer de er i, når du modtager dem, indtil de er sendt.

Jeps.

> Hvis du derimod skal gemme flere blokke indtil du har en hel pakke,
> er du vel nødt til at allokere en buffer som du kan gemme dem i,
> indtil de kan sendes. Det er denne buffer du ikke kender størrelsen
> på, og som du dermed skal lade gro indtil du kan sende pakken.

Jeps... derfor malloc() og strcat() kaldene. Jeg kan, til hver en tid,
sende de data jeg har. Problemet er at få et rimeligt forhold mellem
CPU- og hukommelsesforbrug.

> Jo, hvis man kun ser på et write() kald i forhold til et malloc()
> kald, men hvis man ser på hele systemet er det ikke sikkert at det
> forholder sig sådan.

Så skal der testes

Tak for svarene I to.

--
Jakob Møbjerg Nielsen | "Nine-tenths of the universe is the
jakob@dataloger.dk | knowledge of the position and direction
http://www.jakobnielsen.dk/ | of everything in the other tenth."
| -- Terry Pratchett, Thief of Time



Jakob Møbjerg Nielse~ (09-12-2003)
Kommentar
Fra : Jakob Møbjerg Nielse~


Dato : 09-12-03 10:28

Mogens Hansen wrote:
>> for (i = 0; i < X; i++) {
>> malloc();
>> }
>> write();
>> free();
>
> Mange malloc og een free ?

Hov... jeg ser lige hvad du mener. Der er selvfølgelig een malloc, mange
realloc og een free.

--
Jakob Møbjerg Nielsen | "Nine-tenths of the universe is the
jakob@dataloger.dk | knowledge of the position and direction
http://www.jakobnielsen.dk/ | of everything in the other tenth."
| -- Terry Pratchett, Thief of Time



Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408921
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste