mikrocontroller.net

Forum: Compiler & IDEs Mengendeklaration in C


Autor: Busi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Kann mir jemand sagen, wie ich Mengen in C syntaktisch richtig
schreibe?
In Pascal würde ich schreiben "if (a in ['a','b','c']) ...".
Gibt es etwas ähnliches auch in ANSI C? Habe im Netz leider keine
Beispiele gefunden.

Gruß
Busi

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, so etwas ist in C kein Sprachbestandteil.

So etwas muss "von Hand" nachprogrammiert werden.


Wenn der Mengenbestandteil ein integer-artiger Typ ist (char, short,
long etc.), dann lässt sich dafür ein switch-case-Konstrukt verwenden,
aber elegant ist das nicht wirklich:

  switch (a)
  {
    case 'a':
    case 'b':
    case 'c':
      // das, was geschehen soll, wenn a € ['a','b','c']
      break;
  }

Eine Alternative wäre die Verwendung einer regex-Library (reguläre
Ausdrücke), aber deren Speicherbedarf ist je nach Komplexität des
auszuwertenden Ausdrucks nicht zu unterschätzen.

Autor: Busi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort. Das ist ein gutes und wahrscheinlich das einzige
Workaround. Ich weiß, daß man ein Mengenverhalten über
Präprozessordirektiven erzwingen kann, das war aber eine sehr
umständliche Aktion und ich weiß auch leider nicht mehr, wie dies
funktioniert hat. Aber mit der Switch-Lösung kann ich gut leben.

Vielleicht kannst Du mir noch eine Frage beantworten? Ich habe immer
wieder versucht Lookup-Tables mit #define ins Flash vom Mikrocontroller
zu programmieren. Leider habe ich das bis heute noch nicht hinbekommen.
Strings kann ich problemlos dort ablegen, aber Arrays vom Typ unsigned
char oder irgendeinen anderen ordinalen Datentyp nicht. Inzwischen weiß
ich, daß ich das Schlüsselwort CODE (bei SDCC) verwenden kann, leider
funktioniert auch das nicht in jedem Fall wie erwartet.

Beispiel: #define abc    {1,2,3,4}
          #define abc[]  {1,2,3,4}
          #define abc[4] {1,2,3,4}
          #define abc[]  (1,2,3,4)

Nichts dergleichen funktioniert.
          #define abc    "1234"
... hingegen funktioniert einwandfrei.

Ist das ein Syntaxfehler von mir oder einfach nicht möglich?

Gruß
Busi

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit #define legst du nichts im Flash ab. Auch dein #define abc "1234"
landet nicht im Flash, sondern belegt später RAM.

Möglicherweise fehlen dir einfach ein paar C-Grundkenntnisse. Die
solltest du bei Gelegenheit auf jeden Fall nachholen, da du sonst immer
wieder über solche grundlegenden Verständnisprobleme stolpern wirst.


Für dein konkretes Problem, schau dir bitte die avr-libc-Doku an. Da
sind schöne Beispiele enthalten, wie man Konstanten und Arrays im Flash
ablegt und wieder abruft. Ich sehe es im Moment als unnötig an, das
hierher zu kopieren, was dort schon seit Jahren steht.

Autor: spy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auh das ist nur bedinngt richtig.
eine
#define ABC "1234"
legt lediglich fest, dass beim compilieren jede freistehende textstelle
ABC (wobei (ABC) als freistehend gild, "ABC" jedoch nicht ...)im
source (sofern das #define in der quelldatei oder einer "includeten"
datei steht) durch "1234" ersetzt wird.

PRINTF(ABC);
würde dann

ABC

ausgeben.

ob es dann im flash oder im ram steht hängt vom programmcode ab.

#define ABC "1234"

foo(){
char* szString = ABC;
printf( szString );
....
}

erzeugt einen variable szString dessen "wert" 1234 bei aufruf von
foo() im ram abgelegt wird. das printf(...) gibt dann 1234 aus.

#define ABC "1234"

foo(){
printf( ABC );
....
}

hier gibt printf(...) auch 1234 aus, allerdings steht dieser "wert"
nicht aus dem ram sondern ist ein teil des codes und steht im flash.

...

Autor: spy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry,

>...
>PRINTF(ABC);
>würde dann
>
>ABC
>
>ausgeben.
>

ist natürlich falsch, richtig ist

>PRINTF(ABC);
>würde dann
>
>1234
>
>ausgeben.

Autor: Busi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Angaben wie #define ABC "abc" müssen im Flash landen, alleine schon
deshalb, weil sie im MAP-File nicht auftauchen und ich so viele Strings
im Programm habe, daß das RAM dafür nicht ausreichen würde. (ok,
vielleicht das XRAM). Im LST-File stehen alle Strings am Ende des
Speicherbereiches für das Programm, (bei meinem Programm 974 Bytes bis
Adresse 0x1362). Im Assembler-Code steht als Area CSEG. Also
Flash-Speicher. Und so viele Bytes deshalb, weil ich ganze
Bildschirmseiten auf Display und RS232 ausgebe. Mag sein, das zur
Laufzeit die Strings einzeln in das RAM geladen werden, wichtig ist ja
nur, daß nicht alle gleichzeitig geladen werden. Aber auch das bedeutet
ja, daß die Adresse im Flash diejenige ist, von der zur Laufzeit geladen
wird.

Mit #define mache ich ja nichts weiter, als eine EQUATION zu bauen,
(EQU in Assembler). Auf die Strings zugreifen tue ich über einen
Pointer. Ergo: Der Stringname ist ein Pointer auf die Adresse, an der
der String steht.

Gruß
Busi

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau doch mal diesen Link an:
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Mit #define kommst du auf jeden Fall nicht weiter, da das nur eine
direktive für den Präprozessor ist.
Das heißt:
#define name "zaphod"
printf("%s", name);

würde nach dem Präprozessorlauf zu:
printf("%s", "zaphod");

Also nur eine simple Ersetzung, der #define selbst verschwindet
komplett. Somit kanns auch keinen Pointer auf diesen String selbst
geben.
Mit
char firstname[] = name;
(wird dann zu char firstname[] = "zaphod";)
hättest du nen Pointer auf den String, der jetzt allerdings im RAM
ist.

Ich hoffe das macht es etwas klarer.
Tom

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@spy: Das ist mir schon klar. Natürlich landet prinzipiell erstmal
alles (vom EEPROM abgesehen) im Flash. Das war aber nicht, was ich
meinte.

Das hier:

printf(ABC);

wird durch den Präprozessor ja umgewandelt in:

printf("1234");

Der String "1234" landet natürlich erstmal im Flash. Das Problem ist
aber, dass er im Endeffekt wieder in den RAM geladen wird, da er nicht
das "PROGMEM"-Attribute besitzt. Bei so einem kleinen String spielt
das wohl keine Rolle, bei größeren kann das ins Gewicht fallen.

> Ergo: Der Stringname ist ein Pointer auf die Adresse, an der
> der String steht.
Ja, aber dein Datenpointer, der daher ins RAM und nicht ins Flash
zeigt.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Aussage von Chris trifft -glücklicherweise- nur für Prozessoren mit
Harvard-Architektur zu; bei anderen Prozessoren sieht das durchaus
anders aus, die brauchen auch kein PROGMEM-Attribut.

Schließlich gibt es ja auch andere µCs als ausgerechnet AVRs ... und
niemand hat in diesem Thread explizit von AVRs geredet.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die Aussage von Chris trifft -glücklicherweise- nur für Prozessoren
> mit Harvard-Architektur zu; bei anderen Prozessoren sieht das
> durchaus anders aus, die brauchen auch kein PROGMEM-Attribut.

Ich bin mir nicht ganz sicher, aber theoretisch bräuchte man bei AVRs
auch kein Progmem-Attribut.

C/C++ unterscheidet schließlich zwischen Compile-Time-Konstanten und
normalen "Konstanten". Man könnte dem gcc nun bestimmt beibringen,
Compile-Time-Konstanten grundsätzlich um Flash abzulegen und über
"LPM" etc. darauf zuzugreifen. Dann bräuchte man keine zusätzlichen
Funktionen zum Lesen mehr und auch kein PROGMEM.
Aber ich meine, das wurde nicht eingeführt, weil ein (const-)Zeiger
dadurch signifikant größer und der Zugriff langsamer werden würde.

Möglich wäre es aber bestimmt, die Flash-Lese-Funktionen einzusparen,
indem man dem Compiler beibringt, dass PROGMEM-Zeiger mit LPM
dereferenziert werden müssen. Stand (AFAIK und IIRC) auch schon mal auf
der avrlibc-Mailingliste oder Webseite.

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Man könnte dem gcc nun bestimmt beibringen,
   Compile-Time-Konstanten grundsätzlich um Flash abzulegen und
   über "LPM" etc. darauf zuzugreifen."

Hmm. Bereits das folgende (banale) Beispiel dürfte zeigen, wie
ausweglos das Unterfangen ist:

   char* p = "bla";
   char buffer[10];

   puts(p);
   p = buffer;
   puts(p);

Beim ersten Aufruf von puts ist p ein ROM-Pointer. Durch die völlig
legale Zuweisung transmogrifiziert p zu einem RAM-Pointer, der dem
zweiten Aufruf von puts übergeben wird.
Daher muss prinzipiell jeder Pointer die Information RAM/ROM-Pointer
mit sich herumschleppen.
Jeder Pointerzugriff, ob Zuweisung oder Dereferenzierung, müsste diese
Zusatzinformation auswerten - eine Unterscheidung in
"Compile-Time-Konstanten" und "normale Konstanten" genügt nicht.

Auch die zweite vorgeschlagene Variante (PROGMEM-Zeiger anders
dereferenzieren) ist zwiespältig, weil bereits das kurze "Beispiel"
ein grundlegendes Problem zeigt: Entweder verhalten sich Pointer so,
wie sie das in C nun mal tun, oder aber man entwickelt spezifische
Nichtportierbarkeiten, wie die Unterscheidung in zwei Pointertypen, die
je nach Kontext unterschiedlich zu gebrauchen sind.

Selbst das hülfe nicht; was soll der Compiler beispielsweise bei
Funktionen mit variabler Argumentenliste (Beispiel: printf()) für Code
generieren?

Es muss zur Laufzeit zwischen den verschiedenen Pointertypen
unterschieden werden, sonst entfernt sich das ganze zunehmend von C.

Etwas provokant ausgedrückt:
AVRs sind ganz wundervolle Microcontroller, C ist eine ganz wundervolle
Programmiersprache, aber zusammenpassen tun sie nicht.

Autor: Torsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist nicht provokant sondern wahr. Obwohl ich in C/C++ 'zu Hause'
bin habe ich aufgegeben einen ATMega in C zu programmieren.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hmm. Bereits das folgende (banale) Beispiel dürfte zeigen, wie
> ausweglos das Unterfangen ist:
> char* p = "bla";

Hm, da sieht man mal wieder wie "C++-geprägt" ich bin. ;-)
In C++ wäre diese Anweisung nicht gut, zumindest deprecated (afaik).
p ist nämlich ein Zeiger auf einen nicht-konstanten Wert, "bla" aber
eine String-Konstante.
Ich meinte diesen Fall (wie man es in C++ sowieso schreiben würde):
const char* p = "bla";

Ich weiß gerade nicht so genau, wie es in C mit "const" aussieht. Ich
meinte aber auf jeden Fall Zeiger auf konstante Werte mit
"Compile-Time-Konstanten"; wenn man "char* p" durchgehen lässt,
funktioniert es logischerweise nicht mehr.

Aber du hast Recht, printf etc. wären immer noch ein Problem, da ein
Parameter keine Compile-Time-Konstante ist.


Sieht wohl doch so aus, als wäre die einzige Lösung ein Pointer mit
einem zusätzlichen Bit, das angibt ob es ein RAM- oder ein ROM-Pointer
ist, was aber wohl vom Speicherverbrauch und der Performance her
unakzeptabel wäre.

Ich überleg gerade, wie man C früher(tm) benutzt hat, als die Rechner
noch mit DOS liefen und zwischen near und far-Zeigern unterschieden
werden musste. Ähnliches Problem, selbe Sprache.
Ich meine TurboPascal hat das Problem gelöst, indem die Pointer eine
Zusatzinfo hatten (bin mir aber nicht sicher).
Weiß hier vielleicht jemand, wie das damals in C lief?

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Weiß hier vielleicht jemand, wie das damals in C lief?

Auf normalen Rechnern hat man es einfacher. Es läuft eh alles im RAM
und initialisierte Daten im Datensegment sind kein Problem, auch damals
nicht. Folglich gab es keine Daten im Codesegment und das Problem
tauchte nicht auf.

Ähnlich macht's ja auch WinAVR. Auch dort sind initialisierte Daten
möglich, beim Start kopiert vom ROM uns RAM, nur kann's halt zum
Platzproblem werden.

Ein Problem ist das nur bei µC-Compilern die "const" Daten auf
Harvard-Maschinen ins ROM legen obwohl laut C-Definition "const" und
non-"const" Pointer in eine Richtung kompatibel sind. Also muss solch
ein Compiler Code erzeugen, der beim Pointer-Zugriff zur Laufzeit die
beiden Adressbereiche unterscheidet.

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"AVRs sind ganz wundervolle Microcontroller, C ist eine ganz
wundervolle Programmiersprache, aber zusammenpassen tun sie nicht."


Das stimmt ganz und garnicht !

Man kann auch Harward-Architekturen ganz wunderbar in C programmieren,
z.B. der 8051 beweist es:

Alle Bibliotheksfunktionen arbeiten mit sogenannten generic Pointern,
d.h. die Pointer benötigen 3 Byte, wobei das 3. Byte den Speichertyp
klassifiziert.
Schreibe ich z.B.:

printf( "blabla" );

wird "blabla" im Flash plaziert.

Schreibe ich aber:

char s1[80] = "blabla";
char * s = s1;
printf( s );

ist s ein generic pointer und es funktioniert auch wie gewünscht. Ohne
memory specifier wird s1 nun aber im default RAM-Typ des memory models
(small: data, large: xdata) abgelegt. Durch:

char code s1[80] = "blabla";

kann man aber wieder die Ablage im Flash erzwingen (spart SRAM).


Ich sehe überhaupt keinen Grund, warum ein AVR-Compiler sowas nicht
können soll.

Daß die Handhabung von Flash-Variablen im AVR-GCC etwas umständlich
ist, ist also ganz alleine eine Sache des AVR-GCC und nicht der
AVR-Architektur.


Aber auch bei µCs mit von Neuman Architektur braucht man trotzdem noch
extra Specifier, um die Lokalisierung von Variablen wahlweise im Flash
, im EEPROM oder im SRAM vornehmen zu können.

Nur Architekturen, wo auch der ausführbare Code im RAM liegt, brauchen
sowas nicht und nur diese sind also wirklich 100% "C-kompatibel".


Peter

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.

   "Alle Bibliotheksfunktionen arbeiten mit sogenannten generic
   Pointern, d.h. die Pointer benötigen 3 Byte, wobei das 3. Byte
   den Speichertyp klassifiziert."

Das ist aber ziemlich ineffizient. Statt einfach einen Pointer zu
dereferenzieren (was bei geeigneten Prozessoren mit zwei Befehlen
umgesetzt werden kann - "lade Pointer in Register" - "lade Wert aus
Speicher, verwende Adresse im Register dafür"), muss das dritte Byte
vor jedem einzelnen Zugriff untersucht werden.

   "Aber auch bei µCs mit von Neuman Architektur braucht man
   trotzdem noch extra Specifier, um die Lokalisierung von
   Variablen wahlweise im Flash, im EEPROM oder im SRAM vornehmen
   zu können."

"storage class specifiers" benötigt man sicherlich, aber die sind
ausschließlich bei der Deklaration von Variablen erforderlich. Zugriffe
auf Pointer sind bei von-Neumann-Prozessoren vom "storage class
specifier" unabhängig, da Speicher nunmal Speicher ist und linear im
Adressraum des Prozessors untergebracht ist.
Auf üblichen Prozessoren ist somit ein Pointer -egal, mit welchem
"storage class specifier" er deklariert ist- ein 16-Bit-Wert, auf den
beliebig zugegriffen werden kann.
Das Lesen von Werten aus RAM oder ROM unterscheidet sich nicht.

Daß das Beschreiben bestimmter Speicherbereiche (Flash oder EEPROM)
nicht mit einem einfachen Speicherzugriff zu erledigen ist, dürfte klar
sein, aber das muss IMHO ein Compiler auch nicht für den Programmierer
erledigen.

Damit ist auch klar, das Controllerarchitekturen wie die MCS-51-Reihe
mit ihrer Unterscheidung in "normales" RAM und XRAM keine wirklich
geeigneter Kandidaten für die Programmierung in C sind.

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rufus T. Firefly,

"Das ist aber ziemlich ineffizient."

Die Effizienz bestimmt sich immer aus der Gesamtperformance !

Wenn ich ein Geschoß wie printf() verwende, dann kostet das immer Zeit,
das bischen Typunterscheidung ist dagegen voll vernachlässigbar.

Schlußendlich bestimmt der Programmablauf, wieviel der gesamten
CPU-Last überhaupt solche Pointerzugriffe ausmachen.

Global etwas als ineffizient zu bezeichnen ist also falsch !


"muss das dritte Byte vor jedem einzelnen Zugriff untersucht
werden."

Nicht zwingend !

memcpy() besteht z.B. aus mehreren Routinen, die Auswertung erfolgt
also nur beim ersten zu kopierenden Byte.


"Damit ist auch klar, das Controllerarchitekturen wie die
MCS-51-Reihe
mit ihrer Unterscheidung in "normales" RAM und XRAM keine wirklich
geeigneter Kandidaten für die Programmierung in C sind."

???

Das ist mir neu !

Was habe ich dann aber all die Jahre (seit etwa 1999) bloß gemacht ?

Nachdem ich C einigermaßen konnte, war es eine richtige Erholung
gegenüber Assemblerprogrammierung (nie wieder PUSH usw.).


Und der Overhead ist fast vernachlässigbar (im Durchschnitt 5..20%).
Die SRAM-Nutzung ist sogar geringer, da der Linker den SRAM viel besser
verwalten kann, als ein Mensch in Assembler.

D.h. ich kriege in C viel größere Projekte im gleichen SRAM unter, als
vormals in Assembler !


Peter

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich meine ja auch nicht, daß man AVR und MCS-51 überhaupt nicht in C
programmieren könne, sondern daß aufgrund deren Architekturen etliche
Probleme auftreten, die man mit einer geradlinigeren
Prozessorarchitektur eben nicht hat.

Natürlich kann man -wie Du es auch gemacht hast- den MCS51 in C
programmieren, aber man muss eben auch an etliche Spezialitäten denken,
an die man bei anderen Prozessoren nicht denken muss.

  "Global etwas als ineffizient zu bezeichnen ist also falsch !"

Ich will mich micht mit Dir über Logik streiten ...

Du vergleichst Äpfel mit Gurken - meine Kritik an der (in)Effizienz von
Pointerzugriffen auf MCS51/AVR mit dem "Wirkungsgrad" der
Programmierung in C auf diesen Controllern.

Anstelle eines Pointerzugriffes, der ein oder zwei Maschinenbefehle
lang ist (ersteres, wenn der Pointer eh' schon in einem
Prozessorregister steht), durch die erforderliche Pointertypüberprüfung
weitere Befehle ausführen zu müssen und sich obendrein die Möglichkeit
zu nehmen, einen Pointer in einem Prozessorregister zu halten, ist
ineffizient. Punkt.

Es ist -vom Standpunkt der Effizienz des Gesamtsystemes her gesehen-
immer sinnvoll, in einer Hochsprache mit einem brauchbar optimierenden
Compiler zu programmieren, ob das nun C, Pascal oder was auch immer
ist. Das bestreite ich nicht; ich programmiere nicht ohne Grund seit
längerem in C (so etwa seit Ende der 80er).
Nur bieten bestimmte Prozessorarchitekturen deutlich bessere
Möglichkeiten für die Programmierung in C als andere.

Vergleicht man -der Rückblick in die Geschichte sei mir an dieser
Stelle gestattet- beispielsweise den Befehlssatz der beiden Prozessoren
6502 und 6809, so ist aufgrund der 16-Bit-Indexregister, die der 6809
hat und der erweiterten Adressierungsarten, die im Zusammenhang mit
diesen Indexregistern möglich sind, ein deutlich kompakterer und
schnellerer Maschinencode möglich, als mit dem nur wenige Jahre älteren
6502.

  "Die SRAM-Nutzung ist sogar geringer, da der Linker den SRAM
  viel besser verwalten kann, als ein Mensch in Assembler."

Dafür musst Du aber kein C einsetzen, dafür sollte ein Assembler, der
einzelne Objektdateien erzeugt, die von einem Linker gelinkt werden,
völlig genügen.

Auch das hat rein gar nichts mit der Geradlinigkeit von
Prozessorarchitekturen zu tun, ob nun von-Neumann oder Harvard ...

Und also bleibt meine Kernaussage, daß sich nämlich die
Harvard-Architektur nur schlecht mit der Programmierung in C verträgt,
bestehen.

Autor: Peter Dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Rufus T. Firefly

"Dafür musst Du aber kein C einsetzen, dafür sollte ein Assembler,
der
einzelne Objektdateien erzeugt, die von einem Linker gelinkt werden,
völlig genügen."


nein, dem ist ganz und garnicht so !

Der Linker weiß, daß ein vom Compiler erzeugtes Objekt bestimmten
Konventionen folgt und kann sich darauf einschießen.

Assemblerprogramme besitzen aber alle Freiheiten und dann muß der
Linker viele Optimierungen abschalten.

Man kann ja den Compiler auch erstmal eine Assemblersource erzeugen
lassen, diese assemblieren und linken.
Bloß kommt dabei in der Regel ein Hex-File raus, das größer und
langsamer ist und mehr SRAM verbraucht.

Deshalb halte ich auch nichts davon, leichtfertig Assembler und C zu
mixen, wenn ein reines C auch schon gut genug ist.


Und da schließt sich auch schon wieder der Kreis:

Effizienz ist immer im Vergleich zu irgendwas.

Es ist müßig, sich beim Hausbau um einen Nagel mehr oder weniger zu
streiten, genau, wie bei einem Programm um einen Zyklus mehr oder
weniger auf 1000 Zyklen bezogen.

Dir scheint es ja sehr wichtig zu sein, aber ich wüßte wirklich nicht,
warum ich um jeden CPU-Zyklus feilschen sollte und immer nach dem
schnellsten jagen muß. Ich sehe einfach überhaupt keinen Sinn darin, ob
die CPU nun zu 60% oder zu 99% nur Däumchen dreht.
Eine Anwendung, die eine gestellte Aufgabe 1000-mal schneller als
gefordert ausführen könnte, ist nicht um einen Fliegenschiß
effizienter.


Es ist mir also völlig wurscht, ob ein generic pointer einen tick
langsamer ist und 0,1% mehr Rechenzeit verbraucht, ich dafür aber 2h
bei der Programmierung spare und das Programm weniger potentielle
Fehlerquellen enthält.


Effizienz in der Softwareentwicklung bedeutet für mich, daß man in
möglichst kurzer Zeit eine möglichst stabile und fehlerfreie und
wartbare Anwendung fertig stellen kann und noch genügend Reserven für
den üblichen Erweiterungsbedarf hat.


Ich bin mir sicher, mit einem MSP340-Compiler würde ich weit weniger
effizient arbeiten, einfach weil ich mit dem Keil C51 viel mehr
Erfahrung habe.



Um es abzuschließen, von-Neumann oder Harvard ist mir scheißegal,
Hauptsache der Compiler kommt damit zurecht (und ich mit ihm).


Peter

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Eine Anwendung, die eine gestellte Aufgabe 1000-mal schneller als
gefordert ausführen könnte, ist nicht um einen Fliegenschiß
effizienter."

Das ist so pauschal nicht ganz richtig, weil die CPU bei der
Programmausführung mehr Strom braucht als im idle- oder
powerdown-Modus.
In bestimmten (zugegeben: weniger häufigen) Anwendungen kann das
durchaus wichtig sein.

Autor: Edgar Renner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Eine Anwendung, die eine gestellte Aufgabe 1000-mal schneller als
gefordert ausführen könnte, ist nicht um einen Fliegenschiß
effizienter."

Das mag sein, das diese 1000fach langsamer Anwendung ihren Job, für
aich betrachtet, effizient genug macht. Trotzdem darf man nicht den
Gesamtzusammenhang verlieren:

Oft laufen auf eine uC mehrer Prozesse gleichzeitig ineinander
verschachtelt. Teilweise in einer getriggerten Mailoop, teilweise
Interruptgesteuert. Nun nutzt es nix, wenn z.B. eine Temeraturregelung
die nur Frequenzen im mHz (=milliHerz) Bereich verabrbeiten muß sich
diese Zeit auch nimmt, dadurch aber die anderen Threads wie z.B.
Reaktion auf Komandos aus der seriellen Schnittstelle nicht mehr genug
Computing-Power kriegen um ihre Aufgabe zu machen.

Und nun sind wir an einem Punkt angelangt, wo es wichtig ist zu kennen
was mein Compiler so anstellt. Und vorallem welche Seiteneffekte
entstehen. Nur dann kann ich abhilfe schaffen.

Deshalb meine ich: Über Performanc nachzudenken ist wichtig, wenn's
global mit der Abarbeitungszeit im Gesamtsystem eng wird. Nicht eher
und auf keinen Fall später.

Grüße

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.