Forum: Compiler & IDEs _delay_ms() falsches timing


von weil die zeit sich so beeilt (Gast)


Lesenswert?

geh hier völlig kaputt...

also sollte eig.  echt gehen

compileroptionen :

-Wall -g2 -gstabs -O3 -funsigned-char -funsigned-bitfields 
-mmcu=atmega2561 -DF_CPU=14745600UL

-avr-gcc version:
 4.1.1 (WinAVR 20070122)

ist doch alles da :

- F_CPU -define (stimmt mit MCU-quarz überein) >> quarz-clk auch 
nachgemessen

- divide clk by 7  fuse-bit ist nicht gesetzt
- optimierung sit an

code
1
#include ...
2
#include <util/delay.h>
3
int main()
4
{
5
//....
6
7
8
 while (D_TRUE)
9
  {
10
   // AH_HandleAction(8);
11
    PORTE^= (0x80);
12
    _delay_ms( (double) 1.0);
13
    VolDummy++;
14
15
  }
16
  return(0);
17
}

wieso macht der delays > 100ms an  dem  togglenden-ausgangspin ???


in der libc-docu steht noch was:

"and applications that otherwise do not use floating-point calculations 
will experience severe code bloat by the floating-point library routines 
linked into the application."

das sagt doch nur das der code sehr viel größer werden kann ...

ich kann mir nicht mehr helfen


wenn ich übrigensm Opuimierung ausschalte dann haut es hin  mit der 
delay-zeit.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Compilefähiger Code?

(double)1.0 ist übrigens ziemlich albern.  Du kannst einfach schreiben
_delay_ms(1), es wird auch simpel funktionieren. ;-)

von weil die zeit sich so beeilt (Gast)


Lesenswert?

es ist doch nun egal was ich schreibe .. mit der "1"  gehts auch nicht 
.. andere hätten wieder gemeckert  weil  der Cast (double) fehlt .

es geht nicht !

>> Compilefähiger Code?  << ??

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

weil die zeit sich so beeilt wrote:

> es ist doch nun egal was ich schreibe ..

(double)1.0 ist doppelt gemoppelt.  Die Konstante 1.0 ist bereits
vom Typ double.

> mit der "1"  gehts auch nicht

Hatte ich auch nicht erwartet.  Die Bemerkung bezog sich nur
darauf, dass der C-Standard dir die Konvertierung der Konstante
1 (vom Typ `int') in den Typ `double' als Automatismus garantiert.

> .. andere hätten wieder gemeckert  weil  der Cast (double) fehlt .

Es gibt keinen plausiblen Grund für den Typecast.  Der einzige dieser
Tage noch plausible Grund wäre die Benutzung einer Integer-Konstanten
als double-Argument innerhalb einer variablen Argumentliste, also
bspw.:
1
printf("%f\n", (double)3);

Allerdings braucht bereits diese Form keinen Typecast mehr:
1
printf("%f\n", 3.0);

>>> Compilefähiger Code?  << ??

Ja, was sollen wir mit deiner Aussage ,,Es geht nicht!'', ohne dass
wir compilierfähigen Code von dir sehen würden, mit dem man das
nachvollziehen kann?

Da diese Makros ganz offensichtlich für den Rest der Welt (im Rahmen
ihrer dokumentierten Bereiche) funktionieren, muss der Fehler ja
irgendwo in deinem Code und/oder deinen Compileroptionen liegen,
daher muss man sich das halt angucken können.

von weil die zeit sich so beeilt (Gast)


Lesenswert?

ah stop ..

vor der schleife standen inits .. kA  an was es liegt aber irgendwas 
machen die mit der delayzeit .

Interrupts / ..

hier verhaut sich alle gegenseitig ..  kein bock mehr .

andere Frage ..

die sache mit  den Volatile-def. und das ganze zeug wo der Optimizer 
einfluss haben kann - ist  das "im" c-Standart festgelegt ?

ich mein irgendjemand muss ja sagen was optimiert werden kann und was 
nicht
in so einem C-code .

oder wie ist das?

hab kein informatik studiert ... hatte nur mal ein semester 
C-programmierung während Kommunikationstechn.Studium

da war nie die rede von volatile und optimierung(s-verhinderung) .

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

weil die zeit sich so beeilt wrote:

> Interrupts / ..

Die müsstest du sperren, wenn die Delays genau werden sollen.

Aber dann verzichtest du besser auf die Delays und organisierst
das Timing gleich mit Timern und Interrupts.

> andere Frage ..

Warum keinen anderen Thread?

> die sache mit  den Volatile-def. und das ganze zeug wo der Optimizer
> einfluss haben kann - ist  das "im" c-Standart festgelegt ?

Der C-Standard ist ein "as if"-Standard: eine Implementierung muss
sich im Ergebnis so verhalten, als hätte sie den Quellcode so
compiliert, wie er aufgeschrieben worden ist.  Diese Regelung gibt
dem Compiler weitgehende Freiheit, was er dabei alles optimieren
kann.

Die Definition für volatile beschreibt dabei, dass die Daten eines
als volatile gekennzeichneten Objekts jeweils an den sogenannten
sequence points den Daten entsprechen müssen, die sich beim formalen
Abarbeiten der dem Standard zu Grunde liegenden abstrakten Maschine
ergeben würden.  Das bedeutet letztlich, dass über diese sequence
points hinweg der Compiler keine Daten eines volatile-Objekts
zwischenspeichern darf.

> hab kein informatik studiert ...

Ich auch nicht.

> da war nie die rede von volatile und optimierung(s-verhinderung) .

Ein ernsthaftes Manko.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch wrote:
> Die Definition für volatile beschreibt dabei, dass die Daten eines
> als volatile gekennzeichneten Objekts jeweils an den sogenannten
> sequence points den Daten entsprechen müssen, die sich beim formalen...

Was ist denn ein "sequence point"?

> ...Abarbeiten der dem Standard zu Grunde liegenden abstrakten Maschine
> ergeben würden.  Das bedeutet letztlich, dass über diese sequence
> points hinweg der Compiler keine Daten eines volatile-Objekts
> zwischenspeichern darf.

IMHO trifft das nicht genau, was volatile macht/machen soll, etwa wenn 
das Lesen eines SFRs einen Effekt auf die Maschine hat. Hier wird nichts 
zwischengespeichert:
1
    SFR;

Der Wert in SFR muss gelesen werden, objwohl er nicht verwendet wird.

"volatile" bedeutet also, daß jedesmal, wenn der Compiler im Fluß an 
einen so gekennzeichneten Zugriff kommt, er diesen auscodieren muss. 
Oder ist das gleichbedeutend mit deiner Formulierung?

von weil die zeit sich so beeilt (Gast)


Lesenswert?

brauch da mehr infos zu ... (volatile und das ganze zeug was man braucht 
um an hardware rumzuschreiben/lesen)



ich hoffe ich find da was geeignetes zu im netz ...

von Falk B. (falk)


Lesenswert?

Lese der den Artikel Interrupt und dessen Links.

von weil die zeit sich so beeilt (Gast)


Lesenswert?

jo danke ..

ich arbeitet an einem zusammengeschuhsterten Projekt  ...  hab viel 
quelltext so bekommen und nur angepasst ...

nach und nach ging einiges  auf dem Board : UARTS, ETH, ..   und  dann 
hab ich mal fürn Performance test (Ethernet)  mal die optimierung 
angeschaltet .. und ab ging die post - aber nur bei dem einfachen test 
halt . alles andere verabschiedete sich ...

so jetzt versuch ich hier  das wieder zum laufen zu bekommen - aber 
zurzeit seh ich nur noch schwarz ..  durch die Opt. kommt es mir vor 
gerät alles durcheinander.

-- nice weekend !

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

weil die zeit sich so beeilt wrote:

> so jetzt versuch ich hier  das wieder zum laufen zu bekommen - aber
> zurzeit seh ich nur noch schwarz ..  durch die Opt. kommt es mir vor
> gerät alles durcheinander.

Nö, die Optimierung bringt nichts durcheinander.

Sondern der Quelltext ist durcheinander bzw. Knaup. Bedank dich bei 
demjenigen, der's verbockt hat...

von weil die zeit sich so beeilt (Gast)


Lesenswert?

>Knaup.< ?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Knaup wie Pfusch oder Murks (obwohl es da feine Unterschiede gibt)

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Immer dieses Gemecker über die Compileroptimierung :-(

Optimiert der Compiler nicht, heißt es:

Wääääääh, der Code ist so lang, wääääh, mein Flash ist voll, wääääh, das 
läuft so langsam, wäääääh, sieht der Compiler das denn nicht?

Optimiert der Compiler, heißt es

Wäääääh, der macht mein Programm kaputt, wääääh, warum geht das nicht, 
wääääh, ich kann nicht debuggen, wääääh, warum macht der Compiler das 
nicht so?

Als Compilerbauer hätte ich aus Frust schon längst alle User 
totgeprügelt.

von (prx) A. K. (prx)


Lesenswert?

Als Kompensation gibt's die Momente in denen Leute erst laut "Compiler 
baut Mist" brüllen um dann kurz drauf peinlich berührt den Schwanz 
einzuziehen. Die Prügeln sich sozusagen selber, das spart Arbeit ;-).

von weil die zeit sich so beeilt (Gast)


Lesenswert?

ja 'schuldigung

ich mein - bin wie gesagt relativ neu in der szene  C und hardware.

und wenn man nie was von optimierung durch den Compi. gehört hat 
geschweige denn von Volatile - Variablen ( hab übrigens am WE mal in 
einige ebooks gesehn zu dem thema - entweder steht garnix drin oder wenn 
ein viertelseitiger abschnitt ohne wirkliche informationen  >>  liegt 
wohl daran das diese bücher eher für den reine PC -programmierung ohne 
direkten hardwarezugriff gemacht worden sind ) .
und dann fängt man so an in der erwartung: "C" geht schon sein gang !

und das macht es auch  bis zum tag wo jmd zu  dir kommt und sagt :" 
schalt doch mal optimizer an!"  ... und du beginnst theoretisch von vorn 
...

also so kommt mir es vor ..


ohne sich das Compiler_manual durchzulesen (Kapital Optim.)  kann man ja 
nicht wissen  wie man programmieren muss  damit trotz Opt.  der zweck 
erfüllt wird.   und wenn man sich dort die einzelnen Optionen ansieht 
die die jeweilige Opt.Stufe einschaltet  -  da brauch man schon ne weile 
um das in den kopf zu bekommen was man so beachten muss beim prog´n.

>>  wär vielleicht auch nochmal was das in dem AVR-Tutorial VERSTÄRKT zu erwähnen 
ist: Optimierung: WAS?(wird verändert)-WANN?/Optim.-Stufe
oder halt verweis aufs GCC manual -  dass man sich dazu vorher mal einen 
kopf macht ...

ich hab noch bis 31.1. zeit - dann is projektabgabe - ich hoffe das wird 
noch was bis dahin

von (prx) A. K. (prx)


Lesenswert?

Falsche herum gedacht. Du solltest berücksichtigen, was der Compiler per 
Sprachdefinition nicht optimieren darf und davon ausgehen, dass er 
alles andere optimieren darf. Sonst rennst du bei jedem Compiler und 
jeder Version erneut gegen die Wand.

von weil die zeit sich so beeilt (Gast)


Lesenswert?

hmm .. ja ..

eine  while(1) - schleife (ziehmlich  ohne inhalt) optimiert er doch 
weg/um oder ?

die ist doch aber laut sprachdef. nicht unzulässig ...

ich kenn e mich mit der sprachdefinition nicht 100%ig aus ..

aber auch z.B.  das 2mal - hintereinander lesen derselben adresse (nicht 
volatile)   (vielleicht allgem. formuliert) ...  ist das in der sprache 
definiert, dass man da volatile benutzen muss ??

von weil die zeit sich so beeilt (Gast)


Lesenswert?

oder  gibt es denn einen text wo explizit definiert wird was der 
Compiler nicht optimieren darf ?

von Oliver (Gast)


Lesenswert?

>eine  while(1) - schleife (ziehmlich  ohne inhalt) optimiert er doch
>weg/um oder ?

Eine while(1)-Endlosschleife optimiert der Compiler nicht weg. Eine 
leere for(int i=0;i<100;i++);-Schleife dagegen kann wegoptimiert werden.

>aber auch z.B.  das 2mal - hintereinander lesen derselben adresse (nicht
>volatile)   (vielleicht allgem. formuliert) ...  ist das in der sprache
>definiert, dass man da volatile benutzen muss ??

Eher umgekehrt: C kennt keine Variablen bzw. Speicherstellen mit 
"Nebenwirkungen". Zweimal hintereinander lesen der selben Adresse ergibt 
nach Sprachdefinition zweimal den selben Wert, also kann der Compiler 
das auf einmal Lesen reduzieren - oder auch auf gar nicht lesen, weil 
der Wert z.B. noch in einem Register steht. Ebenso ist per 
Sprachdefinition die Reihenfolge von Lesezugriffen nicht festgelegt. 
Auch die darf der Compiler verändern.

Daraus folgt ganz einfach: Wenn eine Adresse im Speicher Nebenwirkungen 
hat (Hardwareregister, ,die sich "von selbst" ändern, Steuerregister, 
denen es nicht egal ist, in welcher Reihenfolge oder ob sie einmal oder 
zweimal geschrieben werden, usw.), mußt du das dem Compiler das 
mitteilen. Ebenso bei Codeabschnitten, die einfach nur Zeit verbrauchen 
sollen.

Oliver

von Stefan B. (stefan) Benutzerseite


Lesenswert?

weil die zeit sich so beeilt wrote:

> eine  while(1) - schleife (ziehmlich  ohne inhalt) optimiert er doch
> weg/um oder ?

Probiere es aus. Die Endlos-Schleife wird nicht wegoptimiert. Wäre ja 
noch schöner!

Wenn sowas kommt, ist das ein dankbares Opfer für eine Wegoptimierung...

{
  int i = 10;
  while(i)
   i--;
}

Da gibt es eine lokale (!) Variable i, die nur runtergezählt wird und 
nach dem Block verschwunden ist/nicht mehr gültig ist/nicht mehr benutzt 
wird. DAS kann der Compiler in der Optimierung ganz rausschmeissen.

Der Unterschied zu while(1);?

Ein einem Fall geht es nach dem while weiter und im anderen Fall nicht. 
Wo es nicht weitergeht, muss der Compiler das auch beachten!

Und im gemischten Fall?

{
  int i = 10;
  while(1)
   i--;
}

Tja. Nach der Optimierung kann das so aussehen:

{
  while(1);
}

Anders, wenn die Variable i in anderen Funktionen / Statements benutzt 
wird also global ist oder eine lokale Variable ist die nach dem 
while-Block verwendet wird hier z.B. als Returnwert.

int foo(void)
{
  int i = 10;
  while(i)
   i--;
  return i;
}

Dann muss tatsächlich runtergezählt werden. Optimierbar ist dann wie das 
gemacht wird.

Der Compiler könnte so optimieren, dass nicht 10x -1 gerechnet wird, 
sondern nur einmal -10. Im Prinzip könnte der Compiler dann die 
while-schleife in Einzelstatements aufrollen und die Einzelstatements 
zusammenfassen.

Oder Compiler kann als Speed-Optimierung i aus dem langsamen Speicher 
lesen, in einem schnellen Register halten/runterzählen und erst am Ende 
der Schleife an eine Stelle im langsamen Speicher zurückschreiben.

{
  volatile int i = 10;
  while(i)
   i--;
}


Noch anders, wenn die Variable i als volatile gekennzeichnet ist. DANN 
muss der Compiler immer damit rechnen, dass die Variable anderswo eine 
Rolle spielt also gelesen/geschrieben wird. Die Variable wird bei jedem 
Zugriff (Prüfung auf 0, Substraktion) aus dem Speicher gelesen und 
geschrieben.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

weil die zeit sich so beeilt wrote:
> und wenn man nie was von optimierung durch den Compi. gehört hat
> geschweige denn von Volatile - Variablen ( hab übrigens am WE mal in

Eine Rechenaufgabe:
1
a = 1
2
b = a+a;

Frage: Wie groß ist b?

2?

Nö, der Wert ist 14, denn ich hab a nach der Zuweisung heimlich 
verändert. Ätsch.

Genau so geht's deinem C/C++-Program, wenn ein Interrupt eine Variable 
verändert und diese nicht volatile ist.

Wenn der Compiler denkt (bzw. denken darf) b sei 2, dann wird er meine 
Änderung nie mitbekommen.

von (prx) A. K. (prx)


Lesenswert?

Stefan B. wrote:

> int foo(void)
> {
>   int i = 10;
>   while(i)
>    i--;
>   return i;
> }

Wird ggf. reduziert zu

int foo(void)
{
    return 0;
}

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

A. K. wrote:

> Wird ggf. reduziert zu
>
> int foo(void)
> {
>     return 0;
> }

Was ggf. weiter reduziert wird zu

von (prx) A. K. (prx)


Lesenswert?

Ja, aber nur wenn nicht verwendet. Das gilt freilich für alle Funktionen 
ohne Seiteneffekte, egal wie gross, egal was sonst drin steht.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ah stimmt :-)

Aber kann bei Verwendung ersetzt werden durch
1
0

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

weil die zeit sich so beeilt wrote:

> und das macht es auch  bis zum tag wo jmd zu  dir kommt und sagt :"
> schalt doch mal optimizer an!"  ... und du beginnst theoretisch von vorn
> ...

Aus diesem Grunde sollte man die Optimierung ja einfach von vornherein
einschalten, auch wenn dies das Debuggen manchmal etwas erschwert.
Sonst, in der Tat: du debuggst zweimal.

von Peter D. (peda)


Lesenswert?

weil die zeit sich so beeilt wrote:
> und das macht es auch  bis zum tag wo jmd zu  dir kommt und sagt :"
> schalt doch mal optimizer an!"  ... und du beginnst theoretisch von vorn
> ...

Das wird in der Regel kommen, weil ohne Optimierung grottenschlechter 
Code erzeugt wird.
Mal grob geschätzt, entspricht das Ausschalten der Optimierung einer 
Reduzierung der Quarzfrequent von 20MHz auf 1MHz.

Es ist auch grundfalsch, dann sämtliche Variablen als volatile zu 
definieren.
Es betrifft eigentlich nur die Variablen für den Datenaustausch mit 
Interrupts.

Und dabei gibt es noch Atomicity zu beachten, sonst gibts race 
conditions.

Durch race conditions sind schon Leute gestorben:
http://courses.cs.vt.edu/~cs3604/lib/Therac_25/Therac_1.html


Peter

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Peter Dannegger wrote:

> Durch race conditions sind schon Leute gestorben:
> http://courses.cs.vt.edu/~cs3604/lib/Therac_25/Therac_1.html

Darüber gibt's auch was in Deutsch:

http://www.uni-koblenz.de/~beckert/Lehre/Seminar-Softwarefehler/Ausarbeitungen/pfeifer.pdf

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.