Memset via schleife

Gast #672625
Lesenswert?
• ▲
▼
Hallo,


ich möchte die variable cache mit 0x00 initialisieren.
Kann mir jemand kurz erläutern welche Variante die bessere oder 
schnellere ist?
1
char cache[1024];
2

3
//Variante 1
4
for (int i=0;i<1024;i++)  cache[i] =0x00;
5

6
//Variante 2
7
memset(cache,0x00,sizeof(cache));

HW: ATMEGA128
Gast #672629
Lesenswert?
• ▲
▼
Ich würde schätzen, daß auf einem AVR beide gleich schnell sind.
Es würde mich nicht wundern, wenn der Compiler erkennt, was die 
for-Schleife tut und diese automatisch durch einen memset-Aufruf 
ersetzt. Dieser wiederum wird (zumindest bei GCC) vom Compiler selbst 
intern dann in die optimale Variante für den jeweiligen Prozessor 
umgesetzt.
#672633
Lesenswert?
• ▲
▼
@ Rolf Magnus (Gast)

>Ich würde schätzen, daß auf einem AVR beide gleich schnell sind.

ICh würde schätzen, dass memset() schneller ist, weil es handoptimiert 
ist (ASM?).

>Es würde mich nicht wundern, wenn der Compiler erkennt, was die
>for-Schleife tut und diese automatisch durch einen memset-Aufruf
>ersetzt.

Würde ich nicht drauf spekulieren.

> Dieser wiederum wird (zumindest bei GCC) vom Compiler selbst
>intern dann in die optimale Variante für den jeweiligen Prozessor
>umgesetzt.

Praktisch. Simulier einfach mal beide im AVR Studio und schau dir die 
benötigten Taktzyklen an.

MFG
Falk
Gast #672735
Lesenswert?
• ▲
▼
> ICh würde schätzen, dass memset() schneller ist, weil es handoptimiert
> ist (ASM?).

Naja, beim AVR gibt's nicht viele Möglichkeiten, einen Speicherblock zu 
kopieren, und der C-Code für die Schleife ist so einfach, daß ich schon 
mit einem optimalen Ergebnis gerechnet hätte.

> Simulier einfach mal beide im AVR Studio und schau dir die
> benötigten Taktzyklen an.

Ich habe kein AVR-Studio, aber ich kann mir den ASM-Code anschauen:

For-Schleife:
1
        ldi r30,lo8(cache)
2
        ldi r31,hi8(cache)
3
.L2:
4
        st Z+,__zero_reg__
5
        ldi r24,hi8(cache+1024)
6
        cpi r30,lo8(cache+1024)
7
        cpc r31,r24
8
        brne .L2

memcpy:
1
        ldi r24,lo8(1024)
2
        ldi r25,hi8(1024)
3
        ldi r30,lo8(cache)
4
        ldi r31,hi8(cache)
5
        st Z+,__zero_reg__
6
        sbiw r24,1
7
        brne .-6

Die memcpy-Variante ist tatsächlich pro Durchlauf einen Taktzyklus 
schneller, aber nur weil bei der for-Schleife das Register r24 in jedem 
Schleifendurchlauf unnötigerweise neu geladen wird. Sonst wären die 
beiden gleich schnell.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren