Страница 1 из 3

Оптимизация Кода

Добавлено: Ср ноя 02, 2016 19:47:53
sTRog
Помогите оптимизировать код. Сейчас он не влазит в attiny13A, а хочу, чтобы взлазил. Переменные вроде и так все по минимуму обьявил.
Спойлер

Код: Выделить всё


#define F_CPU 1200000UL
#include <util/delay.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define T_POLL 136


char mod = 0;
volatile uint8_t i;
volatile uint16_t Sec;
int rantime;

ISR(TIM0_OVF_vect)
{	
	TCNT0 = T_POLL;
	i++;

   if (i>=10) //period 1s
   {   
      Sec++;
	  i=0;
   }
}


int main(void) {

	PRR = (1<<PRADC); // shut down ADC
	
	TIMSK0 = (1<<TOIE0);  // timer0 overflow interrupt enable
    TCCR0B = (1<<CS02) | (1<<CS00); // prescaler 1/1024
	
  
   i=0; Sec=0;

   sei();

   
   DDRB |=(1<<2); //транзистор
   DDRB |=(1<<3); //cветодиод З
   DDRB |=(1<<4); //cветодиод К
   DDRB &=~(1<<1); //кнопка

   rantime = 3600 + random()%3600;
 
while (1)
{
	if (mod==0)
	{
	if (Sec>=5400)
	{	
	PORTB |= (1<<2);
	_delay_ms(1);
	PORTB &=~(1<<2);
	_delay_ms(10);
	PORTB |= (1<<2);
	_delay_ms(1);
	PORTB &=~(1<<2);
	_delay_ms(500);
	PORTB |= (1<<2);
	_delay_ms(1);
	PORTB &=~(1<<2);
	_delay_ms(10);
	PORTB |= (1<<2);
	_delay_ms(1);
	PORTB &=~(1<<2);

	Sec = 0;
	}
	}

	if (mod==1)
	{
	if (Sec>=rantime)
	{	
	PORTB |= (1<<2);
	_delay_ms(1);
	PORTB &=~(1<<2);
	_delay_ms(10);
	PORTB |= (1<<2);
	_delay_ms(1);
	PORTB &=~(1<<2);
	_delay_ms(500);
	PORTB |= (1<<2);
	_delay_ms(1);
	PORTB &=~(1<<2);
	_delay_ms(10);
	PORTB |= (1<<2);
	_delay_ms(1);
	PORTB &=~(1<<2);

	
	Sec = 0;
	rantime = 3600 + random()%3600;
	}
	}
	
	
	if (PINB & (1<<1)) //
	{
		
		cli();

		if (mod==0) //
		{
			mod = 1;
			Sec = 0;
			
			
			PORTB |= (1<<3);
			_delay_ms(10);
			PORTB &=~(1<<3);
			
			_delay_ms(1000);
			
		}
		else //
		{
			mod = 0;
			Sec = 0;
			
			PORTB |= (1<<3);
			_delay_ms(10);
			PORTB &=~(1<<3);
			_delay_ms(100);
			PORTB |= (1<<3);
			_delay_ms(10);
			PORTB &=~(1<<3);

			_delay_ms(1000);
		}
		
		sei();
	}
}
}


Re: Оптимизация Кода

Добавлено: Ср ноя 02, 2016 20:19:39
Z_h_e
может просто включить оптимизацию?

Re: Оптимизация Кода

Добавлено: Ср ноя 02, 2016 20:37:35
COKPOWEHEU
Половину места занимает random(). Попробуйте поискать реализацию полегче.

Re: Оптимизация Кода

Добавлено: Ср ноя 02, 2016 20:42:06
sTRog
COKPOWEHEU писал(а):Половину места занимает random(). Попробуйте поискать реализацию полегче.
У меня все это ради этой функции, без нее никуда

Re: Оптимизация Кода

Добавлено: Ср ноя 02, 2016 21:29:43
kappz
А так влазит ?
Спойлер

Код: Выделить всё


#define F_CPU 1200000UL
#include <util/delay.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define T_POLL 136


volatile uint8_t i;	// если регистр OCR0B использоваться не будет то закомментируйте эту строку
//#define i OCR0B  	// и раскомментируйте эту


volatile uint16_t Sec;



ISR(TIM0_OVF_vect)
{   
   TCNT0 = T_POLL;
 
   uint8_t li = i;
   
   li++;

   if (li>=10) //period 1s
   {   
      Sec++;
     li=0;
   }
   i = li;
}


static void delay_ms(uint16_t dl) {
	while(dl) {
		_delay_ms(1);
		dl--;
	}
}

int main(void) {

	char mod = 0;
	int rantime;

   //PRR = (1<<PRADC); // shut down ADC .. зачем ? 


   TIMSK0 = (1<<TOIE0);  // timer0 overflow interrupt enable
    TCCR0B = (1<<CS02) | (1<<CS00); // prescaler 1/1024
   
 
   //i=0; Sec=0; // глобальные переменные и так содержат нули

   sei();

   
   DDRB |=(1<<2); //транзистор
   DDRB |=(1<<3); //cветодиод З
   DDRB |=(1<<4); //cветодиод К
   DDRB &=~(1<<1); //кнопка

   rantime = 3600 + random()%3600;
 
while (1)
{
   if (mod==0)
   {
   if (Sec>=5400)
   {   
   PORTB |= (1<<2);
   delay_ms(1);
   PORTB &=~(1<<2);
   delay_ms(10);
   PORTB |= (1<<2);
   delay_ms(1);
   PORTB &=~(1<<2);
   delay_ms(500);
   PORTB |= (1<<2);
   delay_ms(1);
   PORTB &=~(1<<2);
   delay_ms(10);
   PORTB |= (1<<2);
   delay_ms(1);
   PORTB &=~(1<<2);

   Sec = 0;
   }
   }

   if (mod==1)
   {
   if (Sec>=rantime)
   {   
   PORTB |= (1<<2);
   delay_ms(1);
   PORTB &=~(1<<2);
   delay_ms(10);
   PORTB |= (1<<2);
   delay_ms(1);
   PORTB &=~(1<<2);
   delay_ms(500);
   PORTB |= (1<<2);
   delay_ms(1);
   PORTB &=~(1<<2);
   delay_ms(10);
   PORTB |= (1<<2);
   delay_ms(1);
   PORTB &=~(1<<2);

   
   Sec = 0;
   rantime = 3600 + random()%3600;
   }
   }
   
   
   if (PINB & (1<<1)) //
   {
      
      cli();

      if (mod==0) //
      {
         mod = 1;
         Sec = 0;
         
         
         PORTB |= (1<<3);
         delay_ms(10);
         PORTB &=~(1<<3);
         
         delay_ms(1000);
         
      }
      else //
      {
         mod = 0;
         Sec = 0;
         
         PORTB |= (1<<3);
         delay_ms(10);
         PORTB &=~(1<<3);
         delay_ms(100);
         PORTB |= (1<<3);
         delay_ms(10);
         PORTB &=~(1<<3);

         delay_ms(1000);
      }
      
      sei();
   }
}
}

Re: Оптимизация Кода

Добавлено: Ср ноя 02, 2016 21:35:40
oleg110592
Надо пробовать - библиотечный делей заменил ассемблерным, си файл немного покурочил :
Спойлер

Код: Выделить всё

#define F_CPU 1200000UL
//#include <util/delay.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#define T_POLL 136


char mod = 0;
volatile uint8_t i;
volatile uint16_t Sec;
int rantime;

void delay_ms(unsigned short ms);	/* Defined in asmfunc.S */

ISR(TIM0_OVF_vect)
{
    TCNT0 = T_POLL;
    i++;
    if (i >= 10) //period 1s
    {
        Sec++;
        i = 0;
    }
}

void delay1ms()
{
    delay_ms(1);
}

void delay10ms()
{
    delay_ms(10);
}

int main(void)
{
    PRR = (1 << PRADC); // shut down ADC
    TIMSK0 = (1 << TOIE0); // timer0 overflow interrupt enable
    TCCR0B = (1 << CS02) | (1 << CS00); // prescaler 1/1024
    i = 0;
    Sec = 0;
    sei();
    DDRB |= (1 << 2); //транзистор
    DDRB |= (1 << 3); //cветодиод З
    DDRB |= (1 << 4); //cветодиод К
    DDRB &= ~(1 << 1); //кнопка
    rantime = 3600 + random() % 3600;
    while (1)
    {
        if (mod == 0)
        {
            if (Sec >= 5400)
            {
                PORTB |= (1 << 2);
                delay1ms();
                PORTB &= ~(1 << 2);
                delay10ms();
                PORTB |= (1 << 2);
                delay1ms();
                PORTB &= ~(1 << 2);
                delay_ms(500);
                PORTB |= (1 << 2);
                delay1ms();
                PORTB &= ~(1 << 2);
                delay10ms();
                PORTB |= (1 << 2);
                delay1ms();
                PORTB &= ~(1 << 2);
                Sec = 0;
            }
        }
        if (mod == 1)
        {
            if (Sec >= rantime)
            {
                PORTB |= (1 << 2);
                delay1ms();
                PORTB &= ~(1 << 2);
                delay10ms();
                PORTB |= (1 << 2);
                delay1ms();
                PORTB &= ~(1 << 2);
                delay_ms(500);
                PORTB |= (1 << 2);
                delay1ms();
                PORTB &= ~(1 << 2);
                delay10ms();
                PORTB |= (1 << 2);
                delay1ms();
                PORTB &= ~(1 << 2);
                Sec = 0;
                rantime = 3600 + random() % 3600;
            }
        }
        if (PINB & (1 << 1)) //
        {
            cli();
            if (mod == 0) //
            {
                mod = 1;
                Sec = 0;
                PORTB |= (1 << 3);
                delay10ms();
                PORTB &= ~(1 << 3);
                delay_ms(1000);
            }
            else //
            {
                mod = 0;
                Sec = 0;
                PORTB |= (1 << 3);
                delay10ms();
                PORTB &= ~(1 << 3);
                delay_ms(100);
                PORTB |= (1 << 3);
                delay10ms();
                PORTB &= ~(1 << 3);
                delay_ms(1000);
            }
            sei();
        }
    }
}
ассемблерный файл назвать например "asmfunc.S" (S большая) и подключить к проекту:
Спойлер

Код: Выделить всё

#define F_CPU 1200000

;---------------------------------------------------------------------------;
; Simple Delay
;---------------------------------------------------------------------------;
; void delay_ms(WORD ms);
; void delay_us(WORD us);

.global delay_ms
.func delay_ms
delay_ms:
	wdr			; Reset WDT
	sbiw	r24, 1		; if (ms-- == 0) return;
	brcs	9f		; /
	ldi	ZL, lo8(F_CPU/4000)	; 1ms delay
	ldi	ZH, hi8(F_CPU/4000)	; 
1:	sbiw	ZL, 1		; 
	brne	1b		; /
	rjmp	delay_ms
9:	ret
.endfunc


.global delay_us
.func delay_us
delay_us:
	ldi	r23, 2
1:	dec	r23
	brne	1b
	sbiw	r24, 1
	brne	delay_us
	wdr
	ret
.endfunc
GCC для авр 5.2.1 вроде:

Код: Выделить всё

   text       data        bss        dec        hex    filename
   1012          4          6       1022        3fe    TestT13.elf

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 10:37:17
Jack_A
Впечатление, что код писался по принципу: занять как можно больше памяти.
Навскидку:
вместо гаргары

Код: Выделить всё

  DDRB |=(1<<2); //транзистор
   DDRB |=(1<<3); //cветодиод З
   DDRB |=(1<<4); //cветодиод К
   DDRB &=~(1<<1); //кнопка
не написать ли

Код: Выделить всё

DDRB =(1<<2) + (1<<3) + (1<<4)
Далее. Все телодвижения при mod==0 и mod==1 на первый взгляд одинаковы, отличаются только условием if (Sec>=5400) или if (Sec>=rantime), так почему бы их не собрать в подпрограмму и вызвать 2 раза ? А еще проще :

Код: Выделить всё

 if  (   ( ( mod==0 ) &&  (Sec>=5400) )  ||  ( ( mod==1 ) && (Sec>=rantime) )   ) 
Насчет включить оптимизатор - кто же спорит, только лучший оптимизатор - это то, что находится между ушами :)
Переписать на асме - даже и не предлагаю, тапками закидають. :(

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 10:57:52
Z_h_e
Запас тапок помешает что ли? :wink:

Для вычисления псеводослучайного числа существуют простые алгоритмы. Смутно помнится делал простой алгоритм много лет назад. Точно его не помню. Каждое последующее число получалось путем какой-то простой математической операцией с предыдущим. Но полезные данные брались из середины числа. Например, нужно 8 битное случайно число. Математика производилась над 16 битными числами, но результатом было 8 битное число, отбросив у 16 битного 4 старших и 4 младших бита. Само собой 16 битное число запоминалось, для следующего вычисления. Я точно разрядности не помню. Математику к сожалению тоже, но она была простая. Визуально ряд чисел был хаотичен, и период повторения вроде тоже был приличный.

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 11:04:20
ARV
что касается random...
наивно полагать, что это на самом деле будет генератор случайных чисел. нет, каждое следующее будет "непердсказуемым" по предыдущему, но при каждом включении питания всегда будет повторяться одна и та же последовательность...
в связи с этим не вижу никакого смысла в использовании этой функции... например, я в некоторых своих проектах в качестве "псевдослучайной последовательности" использовал последовательное считывание flash микроконтроллера с накладыванием на полученные байты какой-то XOR-маски.
можно сгенерировать псевдослучайную последовательность на основе какого-то циклического алгоритма, отказавшись от библиотечной функции с гарантированно большим периодом повторения...

то есть я предлагаю пойти по пути упрощения требований к решению задачи.

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 11:33:33
BOB51
Да весьма хорошая реализация алгоритма ГСЧ на ассемблере имеется...
:roll:

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 12:21:43
Z_h_e
Тоже абсолютно не к чему получать большое случайное число, чтобы потом разделить опять на большое. Надо сразу определить предел рандома,
Спойлер
/** \ingroup avr_stdlib
Highest number that can be generated by random(). */
#define RANDOM_MAX 0x7FFFFFFF

/**
\ingroup avr_stdlib
The random() function computes a sequence of pseudo-random integers in the
range of 0 to \c RANDOM_MAX (as defined by the header file <stdlib.h>).

The srandom() function sets its argument \c seed as the seed for a new
sequence of pseudo-random numbers to be returned by rand(). These
sequences are repeatable by calling srandom() with the same seed value.

If no seed value is provided, the functions are automatically seeded with
a value of 1.
*/
extern long random(void);
/**
\ingroup avr_stdlib
Pseudo-random number generator seeding; see random().
*/
extern void srandom(unsigned long __seed);

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 13:13:59
ozonn
sTRog писал(а):
COKPOWEHEU писал(а):Половину места занимает random(). Попробуйте поискать реализацию полегче.
У меня все это ради этой функции, без нее никуда
я использую счетный регистр какого-либо таймера. Хотя, это не всегда возможно. Зато число получается по-настоящему случайное

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 14:52:35
ARV
ozonn писал(а):Зато число получается по-настоящему случайное
с чего это вдруг? в однообразной программе, опрашивающей периодически таймер, тактируемый от того же источника, что и ядро МК, получаемые результаты будут строго детерминированы.

при наличии внешних прерываний, поступающих НА САМОМ ДЕЛЕ в непредсказуемые моменты, ваш подход еще как-то может быть оправдан, хотя получаемые числа и в этом случае будут ОЧЕНЬ далеки от случайных и даже от псевдослучайных... и только тактирование таймера от внешнего нестабилизированного генератора как-то может улучшить ситуацию...

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 15:10:57
ozonn
ARV писал(а): при наличии внешних прерываний, поступающих НА САМОМ ДЕЛЕ в непредсказуемые моменты, ваш подход еще как-то может быть оправдан, хотя получаемые числа и в этом случае будут ОЧЕНЬ далеки от случайных и даже от псевдослучайных... и только тактирование таймера от внешнего нестабилизированного генератора как-то может улучшить ситуацию...
именно в непредсказуемые моменты и числа при этом получаются случайные. Разумеется в диапазоне 0 - 255

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 16:07:52
smacorp
ozonn писал(а):именно в непредсказуемые моменты и числа при этом получаются случайные. Разумеется в диапазоне 0 - 255
Вы ошибаетесь. Не рассказывайте Вашу версию криптографам, они повеселятся. Как и Энштейн с его теорией вероятностей. :)

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 16:16:56
ozonn
smacorp писал(а):
ozonn писал(а):именно в непредсказуемые моменты и числа при этом получаются случайные. Разумеется в диапазоне 0 - 255
Вы ошибаетесь. Не рассказывайте Вашу версию криптографам, они повеселятся. Как и Энштейн с его теорией вероятностей. :)
нет, не ошибаюсь

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 16:21:23
smacorp
ozonn писал(а):нет, не ошибаюсь
"Блажен, кто верует, тепло ему на свете!" (с) 8)

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 16:36:00
ozonn
smacorp писал(а):
ozonn писал(а):нет, не ошибаюсь
"Блажен, кто верует, тепло ему на свете!" (с) 8)
не могу вам запретить веровать. Могу лишь посоветовать почитать теорию вероятностей.

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 18:01:04
ARV
ozonn писал(а):именно в непредсказуемые моменты
для работающей программы в МК непредсказуемые моменты могут возникать ТОЛЬКО по внешним событиям - я писал про прерывания. любые ВНУТРЕННИЕ события будут однозначно предсказуемыми.

то есть ваш подход сработает для "электронного кубика" или "однорукого бандита". но устройство, генерирующее текст, выбирая слова из массива по "случайному" индексу, будет генерировать всегда одинаковую последовательность фраз, т.е. однозначно предсказуемо.

Re: Оптимизация Кода

Добавлено: Чт ноя 03, 2016 19:06:06
smacorp
Да ozonn тупо просто не хочет понять о чём ему пытаются сказать уже несколько человек. Да и хрен бы с ним, чо.