AVRGCC: Konstanten optimieren

OP #1312049
Lesenswert?

Hallo,

ich habe das Problem, dass der GCC 2 Konstanten teilen soll. Diese 
rechnet er aber nicht vorher aus, sondern will diese während der 
Laufzeit ausrechnen. Wie bekomme ich den GCC dazu, diese doch bitte 
vorher auszurechen?

======
void highvoltage_control(void){
  unsigned int voltage;

  // Hole aktuelle Spannung
  voltage=adc_read(ADC_supplyvoltageref);
  // Multipliziere mit 64, rechne koeffizenten aus, und gebe den auf
  // das Timer2 register.
  OCR2=(voltage<<6)/(voltage+((HIGHVOTLAGE_plus)/(HIGHVOTLAGE_SUPPLY_resis 
tor_divider)));
}======

Es geht um die letzen 2 Konstanten. Die könnte er ja ganz bequem vorher 
ausrechen. Nur wie bringe ich ihn dazu?

Vielen Dank für Eure Hilfe!

Michael
OP #1312079
Lesenswert?

Die Defines:
=========================
// ADC adress of the supplyvoltage
#define ADC_supplyvoltageref 3
// ADC adress of the highmosfet voltage
#define ADC_highmosfet 6

// Equal reference value that is added to the supplyvoltage val
#define HIGHVOTLAGE_plus 10240
// Tollerance that is substaceted from the actual val
#define HIGHVOLTAGE_tol 100

// Hardware definded voltage divider (Supply voltage)
#define HIGHVOTLAGE_SUPPLY_resistor_divider 13
// Hardware definded voltage divider (High voltage)
#define HIGHVOTLAGE_STEPUP_resistor_divider 21
=========================

Optimierung ist auf size. (Also -Os)
OP #1312125
Lesenswert?

Ich habe auch GCC 3.4.4:
=======================================
avr-gcc (GCC) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is 
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.
=======================================

Auchtsch! Oh mein Gott, war ich blind! Der GCC macht es richtig, der 
rechnet ja eine aus, die man nicht vorher ausrechnen kein.

Sorry GCC, sorry Leute, dass ich euch belästigt habe, dass war ein 
Doofheitsfehler wie er im Buche steht.

Gebe es aber nicht noch eine Möglichkeit, die Division zu vermeiden und 
den Hardware Multiplizierer zu Nutzen?
#1312130
Lesenswert?

Klar doch. Mit dem Kehrwert multiplizieren. Klingt aber einfacher als es 
ist, weil ganzzahlig etwas haarig. Soll heissen: mit (Kehrwert*(2**N)) 
multiplizieren, möglichst ohne Überlauf, und dann durch (2**N) 
dividieren. Das Ergebnis liegt ggf. um eins daneben, was hier aber wohl 
nicht so tragisch sein dürfte.
#1312492
Lesenswert?

Teiler schrieb:
>>Schema:
>>x / 3
>>ersetzen durch
>>(x * (65536/3)) / 65536
>
> d.h. Du optimierst von einer Division auf *eine Multiplikation und*
> zwei Divisionen? Na dann Mahlzeit!

Die eine Division ist konstant und wird bereits vom Compiler erledigt.
Die andere Division ist eine Division durch eine 2-er Potenz und kann 
deaher mittels Schieben oder bei besonderen Zahlen durch 'schrägen' 
Bytezugriff ins Ergebnis erledigt werden.

Multiplikation kann mit Hilfe der Hardware-Multiplikation erledigt 
werden.

D.h. Die Optimierung lautet:
Von einer Software-Division auf
* eine Hardwaremultiplikation
* und ein paar Schiebebefehle (in dem Fall ist es noch nicht mal
  ein Schiebebefehl, sondern vom 32 Bit Ergebnis werden die unteren
  16 Bit verworfen).

Das ist doch nicht schlecht!
Moderator Persönliche Seite #1336347
Lesenswert?

Master Snowman schrieb:
> ich bin durch die suchfunktion auf diesen thread gestossen, weil ich
> auch oft x / 10 rechnen muss...

*1/10 ist schon ziemlich oft durchgekaut. Siehe z.B. avrfreak 
Tutorial-Forum, http://www.cs.uiowa.edu/~jones/bcd/divide.html , SuFu

>>Schema:
>>x / 3
>>ersetzen durch
>>(x * (65536/3)) / 65536
>
> nun, wenn ich das ganzzahlig und mit x = 12 nachrechne, funktioniert das
> aber nicht...

Hälfte des Divisors zum Dividenden addieren
#1336375
Lesenswert?

Master Snowman schrieb:

> nun, wenn ich das ganzzahlig und mit x = 12 nachrechne, funktioniert das
> aber nicht...

Ich hatte davor selbst schon geschrieben, dass das Ergebnis einer 
solchen Rechnung gern um 1 daneben liegt. Weil Rundung in anderer 
Richtung.

Hier ging es um die Umrechnung eines ADC-Ergebnisses. Da ist ein solcher 
Fehler oft zu verschmerzen.

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