Legato
Guest
Tue Jan 30, 2007 3:11 pm
Witajcie.
Wziąłem prosty program i skompilowałem go dwóch środowiskach
programistycznych celem porównania wielkości kodu wynikowego.
1. Mikropascal
2. AVR Studio + GCC
Zadaniem programu testowego było utworzenie migacza z diody LED.
W C:
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 4000000
#define CYCLES_PER_US ((F_CPU+500000)/1000000)
#define LED_ON sbi(DDRD,PD0);sbi(PORTD,PD0)
#define LED_OFF sbi(DDRD,PD0);cbi(PORTD,PD0)
int main (void)
{
for (;
{
LED_ON;
_delay_ms(1000);
LED_OFF;
_delay_ms(1000);
}
return (0);
}
2. Pascal:
program miagacz;
procedure wait;
begin
Delay_ms(300);
end;
begin
DDRD:=$FF;
while true do
begin
PORTD:=$FF; // włącz
wait;
PORTD:=$00; // wyłącz
wait;
end;
end.
Wynik był następujący (porównanie wielkości pliku .hex):
C: 9697 bajtów + 13 bajtów plik *.eep
mikroPascal : 300 bajtów
Jak zminiejszyć "objętość" programu w C ?
Chciałem wybrać C jako narzędzie do oprogramowania chipów ale
składnia i prostota mikroPascala zdecydowanie przemawia za nim.
Pozdrawiam
L.
Krzysztof Kajstura
Guest
Tue Jan 30, 2007 3:21 pm
Quote:
Jak zminiejszyć "objętość" programu w C ?
Włącz opcję -Os w GCC.
pozdrawiam
Krzysztof Kajstura
--
www.kristech.eu
Development Boards and Tools
Saper/nolin11
Guest
Tue Jan 30, 2007 8:14 pm
Legato wrote:
Quote:
Witajcie.
Wziąłem prosty program i skompilowałem go dwóch środowiskach
programistycznych celem porównania wielkości kodu wynikowego.
1. Mikropascal
2. AVR Studio + GCC
Zadaniem programu testowego było utworzenie migacza z diody LED.
W C:
#include <avr/io.h
#include <util/delay.h
napisz własny delay.h+delay.c
Quote:
#define F_CPU 4000000
#define CYCLES_PER_US ((F_CPU+500000)/1000000)
#define LED_ON sbi(DDRD,PD0);sbi(PORTD,PD0)
#define LED_OFF sbi(DDRD,PD0);cbi(PORTD,PD0)
int main (void)
{
for (;
{
LED_ON;
_delay_ms(1000);
LED_OFF;
_delay_ms(1000);
}
return (0);
}
Mi wyszło takie coś:
#include <avr/io.h>
#include "delay.h"
#define LED1_ON {PORTD |= 0x01; } // PD0
#define LED1_OFF {PORTD &= ~(0x01); } // PD0
/*
-------------------------------------------------------------
Główna procedura
-------------------------------------------------------------
*/
int main(void) {
DDRD |= 1 << 0; // PD0- output
for (;

{
LED1_ON;
delay1s8(1);
LED1_OFF;
delay1s8(1);
}
}
194 bajty mi wyszło, a jak użyłem standardowej biblioteki delay: 206 bajty,
I przy różnych optymalizacjach:
0 - 1114b
1 - 552b
2 - 230b
3 - 242b
s - 206b
Oczywiście w drugim przypadku z <ulil/delay.h> ,a z piewrszym nie chce mi
się

....
A zresztą co mi tam

:
0 - 376b
1 - 194b
2 - 218b
3 - 230b
s - 194b
Wszystkie testy na AVR-GCC 3.4.6
--
Saper/nolin11
majl:nolin11_USUN_TO_@interia.pl
gg:4476700
Saper/nolin11
Guest
Tue Jan 30, 2007 9:10 pm
Piotr Chmiel wrote:
Quote:
On Tue, 30 Jan 2007, Saper/nolin11 wrote:
}
194 bajty mi wyszło, a jak użyłem standardowej biblioteki delay: 206
bajty, I przy różnych optymalizacjach:
0 - 1114b
1 - 552b
2 - 230b
3 - 242b
s - 206b
Oczywiście w drugim przypadku z <ulil/delay.h> ,a z piewrszym nie chce
mi się

....
A zresztą co mi tam

:
0 - 376b
1 - 194b
2 - 218b
3 - 230b
s - 194b
Wszystkie testy na AVR-GCC 3.4.6
Strasznie kiepskie to GCC
Ja w IARze wycisnąłem z własną biblioteką delay.h zaledwie 122 bajty
kodu. Wywalając z biblioteki delay.h mnożenie mógłbym urwać jeszcze pare
bajtów
Nie chce mi się pisać tak wygląda moja delay.c:
void delay100us8(uint8_t t) {
while (t>0) {
delayus8(100);
--t;
}
}
void delay1ms8(uint8_t t) {
while (t>0) {
delay100us8(10);
--t;
}
}
void delay100ms8(uint8_t t) {
while (t>0) {
delay1ms8(100);
t--;
}
}
void delay1s8(uint8_t t) {
while (t>0) {
delay100ms8(10);
t--;
}
}
Tak jak widzisz wywołuje hierarchicznie

,a nie od ręki :)
--
Saper/nolin11
majl:nolin11_USUN_TO_@interia.pl
gg:4476700
Adam Dybkowski
Guest
Wed Jan 31, 2007 2:54 am
Legato napisał(a):
Quote:
Wziąłem prosty program i skompilowałem go dwóch środowiskach
programistycznych celem porównania wielkości kodu wynikowego.
1. Mikropascal
2. AVR Studio + GCC
Zadaniem programu testowego było utworzenie migacza z diody LED.
[...]
Quote:
C: 9697 bajtów + 13 bajtów plik *.eep
mikroPascal : 300 bajtów
A dlaczego dla porównania nie napisałeś takiego samego migacza w
asemblerze? Kod wynikowy będzie liczył pewnie kilkadziesiąt bajtów, kod
źródłowy nie będzie raczej dłuższy ani bardziej skomplikowany niż w
języku C. Porównuj lepiej długość kodu binarnego (po konwersji hex2bin)
a nie pliku hex.
Wracając do tematu: sam kod wynikowy "właściwy" funkcji migającej w C ma
kilkanaście bajtów, dodatkowo funkcja opóźniająca nieco dodaje. Reszta
to biblioteka standardowa (głównie start programu w C). Można oczywiście
pewnymi sztuczkami wyeliminować te dodatki, ale tylko w tym konkretnym
przypadku.
Twoją funkcję sprawdziłem kompilując kod dla procesora ATmega128
kompilatorem avr-gcc 4.1.1 (WinAVR 20070122). No to po kolei:
1) używasz chyba starego kompilatora gcc, w nowej wersji nie ma już makr
sbi ani cbi - zastąpiłem odpowiednimi sekwencjami |= i &=~
2) wynikowy plik binarny ma 228 bajtów (w Makefile'u nie dołączam
bibliotek do printf'ów ani matematycznej - może to u Ciebie jest problemem?)
3) pierwsze 140 bajtów kodu wynikowego to wektory przerwań, tu można
oszczędzić najwięcej nie korzystając ze standardowych plików startowych
(opcja -nostartfiles) ale wtedy najczęściej musiałbyś zapewnić także
własne funkcje: zerującą sekcję danych .bss (__do_clear_bss) i
przepisującą sekcję .data (__do_copy_data) a wcześniej ustawić wskaźnik
stosu i wyzerować r1
4) oczywiście dla mniejszych procesorów będzie mniej wektorów przerwań -
program skompilowany dla np. ATtiny22 (wykorzystujący PORTB i DDRB bo
nie ma portu D w tym procu) ma tylko 88 bajtów binariów
5) możesz zainicjować raz a dobrze rejestr DDR a potem tylko migać pinem
portu - binaria schodzą do 86 bajtów
6) na koniec rozwiązanie totalne czyli wywalenie standardowego startupu
(patrz pkt. 3) i niekorzystanie z biblioteki standardowej (opcja
-nostdlib) daje wynikowy plik binarny długości 28 bajtów.
Czy taka optymalizacja ma sens? Oczywiście nie ale to już inna sprawa.
Finalny kod źródłowy w C dający 28-bajtowy binarny plik wynikowy (do
linkera dorzucone opcje -nostartfiles i -nostdlib):
#define F_CPU 4000000
#include <avr/io.h>
#include <util/delay.h>
#define LED_ON PORTB |= (1 << PB0)
#define LED_OFF PORTB &= ~(1 << PB0)
int main (void)
{
DDRB |= (1<<PB0);
for (;
{
LED_ON;
_delay_ms (1000);
LED_OFF;
_delay_ms (1000);
}
return 0;
}
--
Adam Dybkowski
http://www.amwaw.edu.pl/~adybkows/
Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.
Jerzy Turynski
Guest
Wed Jan 31, 2007 6:29 am
Adam Dybkowski <adybkows12@45wp.pl>
napisał w news:epot2n$kak$1@nemesis.news.tpi.pl...
Quote:
Legato napisał(a):
Wziąłem prosty program i skompilowałem go dwóch środowiskach
programistycznych celem porównania wielkości kodu wynikowego.
1. Mikropascal
2. AVR Studio + GCC
Zadaniem programu testowego było utworzenie migacza z diody LED.
[...]
C: 9697 bajtów + 13 bajtów plik *.eep
mikroPascal : 300 bajtów
A dlaczego dla porównania nie napisałeś takiego samego migacza w
asemblerze? Kod wynikowy będzie liczył pewnie kilkadziesiąt bajtów, kod
źródłowy nie będzie raczej dłuższy ani bardziej skomplikowany niż w
języku C. Porównuj lepiej długość kodu binarnego (po konwersji hex2bin)
a nie pliku hex.
[...]
Finalny kod źródłowy w C dający 28-bajtowy binarny plik wynikowy (do
linkera dorzucone opcje -nostartfiles i -nostdlib):
[...]
Nie, panie Adamie!
"Finalny kod źródłowy" ma zawsze dokładnie tyle samo bitów, tj. tyle,
ile potrzeba do zdefiniowania ściśle tożsamej maszyny Turinga [może
być w dowolnie innej formie ściśle tożsamego "rachunku/języka"].
Tego typu "pojęcia" jak "finalny kod źródłowy" to informatyczka dla
bardzo małych chłopców, istniejące tylko po to, by ci mogli się ścigać
w tym, który "ma większego"... [p. niżej: <<zwykłem je zostawiać dla
młodzieży, która lubi studiować raporty typu best buy>>]
To jest błąd ZASADNICZY, jakościowy, dotyczący fałszywego sposobu
pseudomyślenia opartego o _znajomość_ uruchamiania black-box'ów.
To błąd analogiczny do sposobu 'myślenia' (czyt. kojarzenia) "naj-
lepszego dżokeja" vs "biologa-koniologa".
Jeden i drugi mogą twierdzić, że na koniach to "znają się najlepiej
ze wszystkich", ale... który ma rację ?
Zauważ pan, iż ten drugi w ogóle może nie umieć jeźdźić na koniu.
Proponuję małe ćwiczenie (mentalne): proszę położyć na stole przed sobą
banana, po czym zastanowić się (głęboko) jakie działania podejmie wobec
owego przedmiotu: a) małpa, b) dziecko, c) bananomatyk (czyt. informatyk
stosowany), d) biolog. (z podziałem na działania widzialne - które są
absolutnie nieistotne (jeśli ???) - i niewidzialne tzn. _mentalne_).
Wystarczy zauważyć, iż dokładnie ostatnim celem (motywem działania) osob-
nika typu d) będzie chęć rywalizacji w zaspokajaniu intencjonalności osob-
ników rodzaju a), b) czy c). [Chyba że d) jest d) tylko z zewnątrz/"na oko",
bo w środku bywa zwykłym a).]
A jeśli spróbować 'uzmysłowić' osobnikowm typu abc) motywacje d), to zaw-
sze i nieustająco otrzymamy efekt: "A o czym w ogóle ten cymbał bredzi
jak potłuczony???"
Powyższe jest równoważne stwierdzeniu, iż żadnego dżokeja (choćby najle-
pszego w dżokejstwie) żaden koń _jako_taki_ w ogóle nie interesuje, i sum-
ma summarum, "dżokej" zna się na koniach równie "dobrze", co moja pani
np. na elektryczności (bo zna obsługę kontaktów, żelazka itd.).
A'propos polecam... ośli most:
<< Raz nawet udało mi się wyjść na jasnowidza.
Sprowadzono mnie do konającego systemu rozproszonego fakturowania, a ja
nie tylko odmówiłem oględzin stanowisk pracy, ale nawet nie raczyłem za-
pytać o wersję używanej bazy danych (miałem po temu dobry powód: więk-
szość produktów uchodzących za bazy danych w środowisku pecetów jest mi
doskonale obca). >>
[ z
http://tinyurl.com/o6ycg ]
i dalej:
<<Szef firmy, który asystował mi przez cały czas (bo też się miał za
infor-matyka), nie mógł wyjść z podziwu, że ja to tak wszystko robię
"na sucho", niczego nie oglądam na ekranie. On to właśnie doszedł do
przekonania, że jestem jasnowidzem. Pełen podziwu chciał mnie zaanga-
żować do nadzoru nad rozbudową systemu, bo firma rośnie. Zapytałem,
czego się spodziewa po rozbudowanym systemie. Zaczął wyliczać, czego
to on nie zamierza kupić: i serwer transakcji, i drukarki laserowe,
i 117 wersję sieci, i kilometry szklanego drutu (bo kumpel tanio sprze-
daje). Przerwałem mu, bo mnie te rzeczy dosyć nudzą i zwykłem je zo-
stawiać dla młodzieży, która lubi studiować raporty typu best buy.
[...]
Teraz to ja wprowadzam potencjalnych kontrahentów na ośli most.
Z najpoczciwszą miną, na jaką mnie stać, patrzę takiemu głęboko
w oczka i pytam: no, a jak już zrobimy panu ten system-marzenie,
jak ruszą dyski, rozjarzą się monitory, zamigocą diody na przyłą-
czach, po klawiaturach zaklekocą wytrenowane palce operatorek i
ze szczelin super drukarek zaczną bezszelestnie wysuwać się super-
dokumenty, to po czym pan szanowny pozna, że system jest dla pań-
skiej firmy przydatny, że się to wszystko panu opłaca?
Kontraktów co prawda nadal nie dostaję, ale jak słodko jest patrzeć
na te opadające szczęki, niemal dosłownie słyszeć pisk mało używa-
nych opon mózgowych po nagłym wciśnięciu hamulca zwątpienia: jak
to, to oprócz tego pięknego widoku doskonale działającego układu
najnowocześniejszych urządzeń, ma się to jeszcze opłacać? To sy-
stem informatyczny nie jest tak jak obraz Chełmońskiego czy innego
Fałata: kupuje się, bo drogi i wiesza na ścianie, żeby mnie podzi-
wiano, żem tyle szmalu wydał? To się ma jeszcze opłacać? Przecież
nowoczesność jest bezcenna! A juści! Czy aby przypadkiem nie bez-
wartościowa? [...] >>
Quote:
--
Adam Dybkowski
JeT.
Janusz
Guest
Wed Jan 31, 2007 7:28 am
Użytkownik "Jerzy Turynski" <jaetear@polaboax.com> napisał w wiadomości
Wielkie ciach!
Quote:
JeT.
Łał, niezły kawałek beletrystyki, tylko co to wnosi do tematu?
JJJK
Legato
Guest
Wed Jan 31, 2007 8:01 am
Adam Dybkowski napisał(a):
Quote:
A dlaczego dla porównania nie napisałeś takiego samego migacza w
asemblerze? Kod wynikowy będzie liczył pewnie kilkadziesiąt bajtów, kod
źródłowy nie będzie raczej dłuższy ani bardziej skomplikowany niż w
języku C. Porównuj lepiej długość kodu binarnego (po konwersji hex2bin)
a nie pliku hex.
Wiem, wiem ale nie napisałem dlatego, że niestety nie znam assemblera :(
Quote:
Wracając do tematu: sam kod wynikowy "właściwy" funkcji migającej w C ma
kilkanaście bajtów, dodatkowo funkcja opóźniająca nieco dodaje. Reszta
to biblioteka standardowa (głównie start programu w C). Można oczywiście
pewnymi sztuczkami wyeliminować te dodatki, ale tylko w tym konkretnym
przypadku.
Zdecydowaną poprawę wniosło ustawienie opcji -Os zaproponowanej przez
kol. Krzysztof Kajstura oraz wyeliminowaniu zbędnych bibliotek.
Quote:
Twoją funkcję sprawdziłem kompilując kod dla procesora ATmega128
kompilatorem avr-gcc 4.1.1 (WinAVR 20070122). No to po kolei:
1) używasz chyba starego kompilatora gcc, w nowej wersji nie ma już makr
sbi ani cbi - zastąpiłem odpowiednimi sekwencjami |= i &=~
Masz rację. Mam avr-gcc-3.4.1 Zabieram się do aktualizacji :)
Quote:
2) wynikowy plik binarny ma 228 bajtów (w Makefile'u nie dołączam
bibliotek do printf'ów ani matematycznej - może to u Ciebie jest
problemem?)
Powiem tak, skompilowałem to "standardowo" jak leci w AVRStudio bez
zastosowania wszelakich "optymizerów" kodu. Stąd wyszło jak wyszło.
Do następnych kompilacji zastosuję się do porad Twoich jak i innych kolegów.
Dzięki Tobie i innym za fajną lekcję :)
Dopiero startuję z pisaniem w C na AVRy więc Twoje uwagi są dla mnie cenne.
Jak by co to pozwolę sobie zamącić Wam w tym temacie głowę.
Pozdrawiam
L.
Legato
Guest
Wed Jan 31, 2007 9:22 am
Adam Dybkowski napisał(a):
Quote:
2) wynikowy plik binarny ma 228 bajtów (w Makefile'u nie dołączam
bibliotek do printf'ów ani matematycznej - może to u Ciebie jest
problemem?)
Nie udało mi się dogonić mistrza.
Wpisując Twoje parametry udało mi się osiągnąć postęp który jest dość
znaczny :)
349 bajtowy plik hex i 116 bajtowy bin
Gdybyś był uprzejmy przeglądnąć plik makefile byłbym Ci wdzięczny.
Oto on:
###############################################################################
# Makefile for the project Migacz
###############################################################################
## General Flags
PROJECT = Migacz
MCU = atmega8
TARGET = Migacz.elf
CC = avr-gcc.exe
## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)
## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -gdwarf-2 -nostartfiles -nostdlib -DF_CPU=4000000UL
-Os -fsigned-char
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d
## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS +=
## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom
HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
## Library Directories
LIBDIRS = -L"F:\avr\winavr\avr\include\avr"
## Objects that must be built in order to link
OBJECTS = migacz.o
## Objects explicitly added by the user
LINKONLYOBJECTS =
## Build
all: $(TARGET) Migacz.hex Migacz.eep size
## Compile
migacz.o: ../migacz.c
$(CC) $(INCLUDES) $(CFLAGS) -c $<
##Link
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o
$(TARGET)
%.hex: $(TARGET)
avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@
%.eep: $(TARGET)
-avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
%.lss: $(TARGET)
avr-objdump -h -S $< > $@
size: ${TARGET}
@echo
@avr-size -C --mcu=${MCU} ${TARGET}
## Clean target
..PHONY: clean
clean:
-rm -rf $(OBJECTS) Migacz.elf dep/* Migacz.hex Migacz.eep
## Other dependencies
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)
Pozdrawiam
L.
Artur M. Piwko
Guest
Wed Jan 31, 2007 12:47 pm
In the darkest hour on Wed, 31 Jan 2007 07:28:09 +0100,
Janusz <janusz_karas@poczta.onet.pl> screamed:
Quote:
JeT.
Łał, niezły kawałek beletrystyki, tylko co to wnosi do tematu?
Absolutnie nic. To taka informatyka przez duże U.
--
[ Artur M. Piwko : Pipen : AMP29-RIPE : RLU:100918 : From == Trap! : SIG:237B ]
[ 11:47:28 user up 11238 days, 23:42, 1 user, load average: 0.06, 0.06, 0.06 ]
And on the seventh day, God wrote documentation (in Ark of the Covenant).
Adam Dybkowski
Guest
Wed Jan 31, 2007 6:37 pm
Jerzy Turynski napisał(a):
Quote:
Finalny kod źródłowy w C dający 28-bajtowy binarny plik wynikowy (do
linkera dorzucone opcje -nostartfiles i -nostdlib):
[...]
Nie, panie Adamie!
"Finalny kod źródłowy" ma zawsze dokładnie tyle samo bitów, tj. tyle,
ile potrzeba do zdefiniowania ściśle tożsamej maszyny Turinga [może
być w dowolnie innej formie ściśle tożsamego "rachunku/języka"].
[...]
Fałata: kupuje się, bo drogi i wiesza na ścianie, żeby mnie podzi-
wiano, żem tyle szmalu wydał? To się ma jeszcze opłacać? Przecież
nowoczesność jest bezcenna! A juści! Czy aby przypadkiem nie bez-
wartościowa? [...]

Ale o so chozi?
Pod pojęciem "finalny kod źródłowy" przytoczyłem poprawioną wersję kodu
źródłowego załączonego przykładu programu w języku C, uwzględniającą
ograniczenia wymuszane przez nowszą wersję kompilatora avr-gcc takie jak
brak makr cbi i sbi. Poza tym w języku C często na kilka sposobów można
zapisać sekwencję dającą ten sam binarny kod wynikowy - więc mój
"finalny kod źródłowy" to tylko przykład poprawienia programu migającego
diodą na jeden z wielu możliwych sposobów.
--
Adam Dybkowski
http://www.amwaw.edu.pl/~adybkows/
Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.