C-Code optimieren

OP #3039241
Lesenswert?

Hallo,

ich habe einen AVR32UC3C0512C, der einen IR-Protokollstack über einen 
8-Bit Parallelbus anspricht. Im späteren Verlauf des Projektes wird der 
µController gewechselt (kleineres Package) bei dem die Pins dann zwar am 
selben Port hängen, aber wild verstreut (reicht von Pin 4 bis Pin 27). 
Nachdem die Kommunikation und alle Routinen grundsätzlich funktionieren, 
würde ich gerne die Geschwindigkeit der Lese- und Schreibroutinen 
erhöhen. Derzeit bin ich bei Übertragungsraten von 2,7 MBit/s von 
(theoretisch) maximalen 4 MBit/s. Nachfolgend der Code, den es zu 
optimieren gilt:
1
/* IPMS Controllerpins definieren */
2
#define GPIO_IPMS_DB0  AVR32_PIN_PD11
3
#define GPIO_IPMS_DB1  AVR32_PIN_PD12
4
#define GPIO_IPMS_DB2  AVR32_PIN_PD13
5
#define GPIO_IPMS_DB3  AVR32_PIN_PD14
6
#define GPIO_IPMS_DB4  AVR32_PIN_PD15
7
#define GPIO_IPMS_DB5  AVR32_PIN_PD16
8
#define GPIO_IPMS_DB6  AVR32_PIN_PD17
9
#define GPIO_IPMS_DB7  AVR32_PIN_PD18
10

11
...
12

13
uint8_t ipms_read_reg(uint8_t address)
14
{
15
  uint8_t data = 0;
16
  uint32_t temp_bitmask = 0;
17

18
  ...
19

20
  /* Pinzustände abfragen */
21
  temp_bitmask = AVR32_GPIO.port[IPMS_DB_PORT].pvr;
22

23
  /* Byte wieder zurecht biegen */
24
  if(temp_bitmask & (1 << (GPIO_IPMS_DB0 & 0x1F)))  data |= 1;
25
  if(temp_bitmask & (1 << (GPIO_IPMS_DB1 & 0x1F)))  data |= 2;
26
  if(temp_bitmask & (1 << (GPIO_IPMS_DB2 & 0x1F)))  data |= 4;
27
  if(temp_bitmask & (1 << (GPIO_IPMS_DB3 & 0x1F)))  data |= 8;
28
  if(temp_bitmask & (1 << (GPIO_IPMS_DB4 & 0x1F)))  data |= 16;
29
  if(temp_bitmask & (1 << (GPIO_IPMS_DB5 & 0x1F)))  data |= 32;
30
  if(temp_bitmask & (1 << (GPIO_IPMS_DB6 & 0x1F)))  data |= 64;
31
  if(temp_bitmask & (1 << (GPIO_IPMS_DB7 & 0x1F)))  data |= 128;
32

33
  ...
34
}

Wie kann ich hier Taktzyklen einsparen? Vor lauter Programmierarbeit, 
habe ich gerade keine Ideen mehr :) Vielleicht liegt es auch daran, dass 
es schon spät ist.....oder früh.

Gute Nacht und vielen Dank im voraus für eure Mühen
Gast #3039246
Lesenswert?

Ist das eine datenbankspeicherplazbelegende Trollfrage, oder dein 
ernst??

Dein Bit0 fängt bei PinD11 an und Bit7 hört bei PinD18 auf. Durchweg.
du brauchst doch nur dein temp_bitmask um 11 bit nach unten verschieben 
und mit 0xff verunden.... fertig.

Du hast dir echt nichtmal eine Minute lang gedanken gemacht, wie man die 
Bitfummelei vereinfachen könnte, oder? :-( Das ist demütigend für jeden 
der hier antworten soll -.-
OP #3039254
Lesenswert?

> Im späteren Verlauf des Projektes wird der
> µController gewechselt (kleineres Package) bei dem die Pins dann zwar am
> selben Port hängen, aber wild verstreut (reicht von Pin 4 bis Pin 27).

Hier steht, dass es sich später nicht mehr so verhält wie im 
Codeschnipsel! Dass es zurzeit so geht, wie du es vorschlägst, ist mir 
klar.
OP #3039257
Lesenswert?

Es geht mir auch eher um einen generellen Hinweis. Aber vielleicht 
sollte ich mal ein Beispiel reinstellen. Das momentane Design sieht 
folgende Pinbelegung vor:
1
  /* IPMS Controllerpins definieren */
2
  #define GPIO_IPMS_DB0  AVR32_PIN_PD11
3
  #define GPIO_IPMS_DB1  AVR32_PIN_PD13
4
  #define GPIO_IPMS_DB2  AVR32_PIN_PD14
5
  #define GPIO_IPMS_DB3  AVR32_PIN_PD21
6
  #define GPIO_IPMS_DB4  AVR32_PIN_PD27
7
  #define GPIO_IPMS_DB5  AVR32_PIN_PD28
8
  #define GPIO_IPMS_DB6  AVR32_PIN_PD29
9
  #define GPIO_IPMS_DB7  AVR32_PIN_PD30
#3039410
Lesenswert?

Johann L. schrieb:
> ein ästhetisches Problem
Vermute ich auch...

Tarek T. schrieb:
> /* Pinzustände abfragen */
Der Kommentar ist redundant. Wer sieht nicht, dass in der Folgezeile ein 
paar Pins eingelesen werden?

Tarek T. schrieb:
> /* Byte wieder zurecht biegen */
Das seh ich auch, dass da was zurechtgebogen-bitgefummelt wird.
Was ist der Zweck der Aktion?
Wenn dir das im Laufcode zu hässlich aussieht, schreib doch eine kleine 
Funktion, die dir das Pin-Einlesen/Zurechtbiegen erledigt. Oder eine 
Inline-Funktion oder ein Makro...

mfg mf
Gast #3039430
Lesenswert?

> bei dem die Pins dann zwar am selben Port hängen, aber wild verstreut

Dann machst du ein mal einen Zugriff
1
temp_bitmask = AVR32_GPIO.port[IPMS_DB_PORT].pvr;
und codierst ein mal um
1
temp_bitmask = umcodier_tabelle[temp_bitmask];
dann sind die Bits dort wo du sie hinhaben willst.

Die Tabelle ist 256 Bytes lang,
du tauscht also die lange Laufzeit deines Programmstücks
1
if(temp_bitmask & (1 << (GPIO_IPMS_DB0 & 0x1F)))  data |= 1;
2
if(temp_bitmask & (1 << (GPIO_IPMS_DB1 & 0x1F)))  data |= 2;
3
if(temp_bitmask & (1 << (GPIO_IPMS_DB2 & 0x1F)))  data |= 4;
4
if(temp_bitmask & (1 << (GPIO_IPMS_DB3 & 0x1F)))  data |= 8;
5
if(temp_bitmask & (1 << (GPIO_IPMS_DB4 & 0x1F)))  data |= 16;
6
if(temp_bitmask & (1 << (GPIO_IPMS_DB5 & 0x1F)))  data |= 32;
7
if(temp_bitmask & (1 << (GPIO_IPMS_DB6 & 0x1F)))  data |= 64;
8
if(temp_bitmask & (1 << (GPIO_IPMS_DB7 & 0x1F)))  data |= 128;
gegen den Speicherplatz den die Tabelle benötigt
space vs. speed trade off
(die man übrigens von einem Hilfsprogramm erzeugen lässt,
bei viel RAM auch zu Beginn des Programms vom Programm
selbst erzeugen lassen kann
1
uint8_t umcodier_tabelle[256];
2
for(i=0;i<256;i++)
3
{
4
  temp_bitmask = i; data = 0;
5
  if(temp_bitmask & (1 << (GPIO_IPMS_DB0 & 0x1F)))  data |= 1;
6
  if(temp_bitmask & (1 << (GPIO_IPMS_DB1 & 0x1F)))  data |= 2;
7
  if(temp_bitmask & (1 << (GPIO_IPMS_DB2 & 0x1F)))  data |= 4;
8
  if(temp_bitmask & (1 << (GPIO_IPMS_DB3 & 0x1F)))  data |= 8;
9
  if(temp_bitmask & (1 << (GPIO_IPMS_DB4 & 0x1F)))  data |= 16;
10
  if(temp_bitmask & (1 << (GPIO_IPMS_DB5 & 0x1F)))  data |= 32;
11
  if(temp_bitmask & (1 << (GPIO_IPMS_DB6 & 0x1F)))  data |= 64;
12
  if(temp_bitmask & (1 << (GPIO_IPMS_DB7 & 0x1F)))  data |= 128;
13
  umcodier_tabelle[i] = data;
14
}

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