Portée des incréments dans une boucle for

Yep!

Je cherche à économiser quelques octets dans mon programme.

J’ai cependant une logique que j’ai du mal à comprendre, je déclare mes increments en byte et pensais bêtement qu’un octet était un octet. Pourtant, lorsque l’on modifie la valeur de l’increment, on constate une économie ou au contraire une consommation supplémentaire de l’espace programme.

Prenons un exemple :

#define led A0

byte value;

void setup() {
  
  pinMode(led, OUTPUT);
  
}

void loop() {
  
  for (byte i = 0; i < 10; i++) {
    analogWrite(led, 10+i);
    delay(200);
  }
  
  analogWrite(led, 0);
}

Je compile = 1214 bytes.
Je modifie i < 10 en i < 1, = 1196 bytes. (ici c’est normal)
Je modifie i < 2, = 1218 bytes. ( 2 executions)
Je modifie i < 3, = 1214 bytes, ( 3 executions)
1214 bytes constant jusqu’à 245, 1216 bytes ensuite.

J’ai déjà 4 bytes dans les choux et je ne les explique pas. En modifiant une seule valeur dans mon programme, de 3 à 4 dans une boucle for, je gagne prés de 30 bytes.
Cà depend naturellement de ce qu’il y a dans la boucle…mais là, je ne vois pas de différence entre :

B00000001 et B00000010 ou B00000010 et B00000011

@+

Zoroastre.

J’observe le même phénomène, il doit y avoir certains critères lors de l’optimisation par le compilateur d’après le nombre d’incrémentation ?

Compilé pour mini

i < 1 //= 1202 bytes
i < 2 //= 1224 bytes
i < 3 //= 1220 bytes : -> 245 
i < 246 //= 1222 bytes : -> 255

Compilé pour mega

i < 1 //= 2018 bytes
i < 2 //= 2040 bytes
i < 3 //= 2036 bytes : -> 245 
i < 246 //= 2038 bytes : -> 255

d’un côté ça voudrait dire qu’il vaut mieux 3 que 2 ??? :sweat_smile:

Yep!

J'avais pensé tout d'abord que la multiplication par 2 nous rapproché des bits de poids fort...mais çà ne marche pas.

C'est clair que cela se passe dans la gestion de la mémoire du compilo. Il doit y avoir un jump en plus ici ou là.

Je ne connais pas assez gcc, en dehors des compilations linux, pour m'aventurer plus dans les hypothèses.

d'un côté ça voudrait dire qu'il vaut mieux 3 que 2 ???

Ben oué, c'est la conclusion du truc... :grin:

@+

Zoroastre.

Yep!

Par contre, aucune modification de 2 à 255 dans ce programme par exemple : 1102 bytes.

/*
Timer output Arduino output Chip pin	Pin name
OC0A	  6	          12	          PD6
OC0B	  5               11              PD5
OC1A	  9	          15	          PB1
OC1B	 10	          16	          PB2
OC2A	 11	          17	          PB3
OC2B	  3	           5	          PD3

### PINS CONFIGURATION ###

DDRD Pins 0-7, DDRB Pins 8-13

### COLUMN ###
latchPin = 8 (PB0)
clockPin = 12 (PB3)
dataPin = 11 (PB4)

### ROW ###
RED = 2N2222 attached to pin 3 (pwm)
BLUE = 2N2222 attached to pin 5 (pwm)
GREEN = 2N2222 attached to pin 6 (pwm)

### SIZE OF SKETCH ###
1288 bytes --> 1186 bytes --> 1148 bytes --> 1102 bytes
*/

#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>

const uint8_t PROGMEM cycle[4] = {
  B01000000,
  B00100000,
  B00001000,
  B00100000
};

void setup() {
  
  DDRD = DDRD | B01101000; // TRANSISTOR
  DDRB = DDRB | B00011001; // ASYNC SERIAL
  
  delay(500);
  
}

void loop() {
  
  for (byte i = 0; i < 4; i++) {
  
  0<<PB0; // Set Pin 8 to LOW
  shiftOut(PB4, PB3, MSBFIRST, B00001101); // 595 port 0, 2, 3 on.
  1<<PB0; // Set Pin 8 to HIGH
  
  PORTD |= pgm_read_byte(&cycle[i]);
  
  delay(500);
  
  PORTD &= B00000011; // Reset all pins, keep TxRx to default
  
  delay(500);
  
  }
  
}

Cà confirme que la compilation est en cause…

@+

Zoroastre.