Отговори на тема  [ 29 мнения ]  Отиди на страница 1, 2  Следваща
бъг в оптимизатора на С30 (С за 30та серия на микрочип) 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение бъг в оптимизатора на С30 (С за 30та серия на микрочип)
при включване на оптимизациите на С30 програмата спря да бачка.
проследих проблема и видях че е във една функция която чете два 16 битови инта и ги връща като един 32 битов. разгледах кода на асемблер и видях следното:
Код:
0700ED     rcall 0x001fae            четем младшата 16 битова дума
9FBFE0     mov.w 0x0000,[0x001e-4] съхранява резултата (намира се във w0) в стековия кадър
0700EB     rcall 0x001fae           четем старшата дума
>>тука компилатора е забравил да я съхрани резултата, трябва да има  mov.w 0x0000,[0x001e-2]
97B86F     mov.w [0x001e-4],0x0000 възстановява младшата дума в регистър w0
97B8FF     mov.w [0x001e-2],0x0002 "възстановява" старшата дума в регистър w1, разбира се нищо не става щото не е записана

резултата от бъга е че прочетените 32 битови числа са със случайно съдържание на старшите 16 бита
кво да кажа освен че задълбочих убеждението си че микрочип не могат да пишат софтуер.
ако размера на кода и скоростта не са критични, моята препоръка е да не се включва оптимизатора, понеже носи риск, това не само на тая платформа а по принцип.


Сря Дек 26, 2007 11:31 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 27, 2005 12:48 pm
Мнения: 6094
Мнение 
по принцип не ползвам "оптимизации"
if then си ги правя сам където е необходимо...

а това където си го описал - сигурен ли си че бъга не е от тебе (процедурата "rcall 0x001fae")
пасни кода да пробвам на мойто С30...

_________________
main[-1u]={1};


Сря Дек 26, 2007 12:23 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
TheWizard написа:
пасни кода да пробвам на мойто С30...


Код:
unsigned long  ReadRSDWord()
{
   int dw[2];
   dw[0]=ReadRSWord();
   dw[1]=ReadRSWord();
   return *((unsigned long*)dw);   
}

това е кода на С, пробвай го, функцията ReadRSWord си сложи някаква която връща инт (16 битов).
оптимизатора е на ниво s, на други нива не съм пробвал, без оптимизация се компилира правилно. що се отнася за това къде е бъга - аз не пиша от вчера и знам че компилатор току така не се обвинява. :)


Сря Дек 26, 2007 1:02 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
Такава простотия ми е правило visual studio 6.
Правилно е да си слижиш явно преобразуване на типа. Също там имаш малко каша с signed/unsigned.
Така би трябвало да не се омотва.
Код:
unsigned long  ReadRSDWord()
{
   unsigned int dw[2];
   dw[0]= (unsigned int)ReadRSWord();
   dw[1]= (unsigned int)ReadRSWord();
   return *((unsigned long*)dw);   
}


A ако искаш да спиш спокойно обясняваш като на малоумен така;
Код:
u64  ReadRSDWord()
{
   union
   {
       u64 lg;
       struct
       {
           u16  low;
           u16  p1;
           u16  hi;
           u16  p2;
        };
   };
   
   lg   = 0;
   low =  ReadRSWord();
   hi   =  ReadRSWord();
   return lg;
}


Сря Дек 26, 2007 1:52 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Ное 21, 2004 11:31 pm
Мнения: 10088
Мнение 
Цитат:
...компилатор току така не се обвинявa...

майкро[чип|софт] oще по-малко - те са безгрешни. :!:

иначе за оптимизациите си прав - трябва да се ползват внимателно и със стратегия за тестване. то самото QA си е наука ако трябва да се прави както трябва. и отнема доста от бюджета на проекта.

доколко хардуерна фирма може да прави софтуер... резултата е същия когато софтуерна фирма прави хардуер. преди 20-30 години моторола си правеже сама софтуера. после обаче си купиха metrowerks и престанаха да се занимават със софтуероправене. от това пострада малко потребителя, защото съпорта на моторола си беше на ниво, но такова е решението на корпорацията - оптимизация на разходите.

изобщо - силиконовата чалга е повсеместна. при нас се изразява предимно в плиткоумни силиконови певачки, а при тях в бъгав силикон от пикльвци, авери, lpc-та и т.н. всеки гони срокове, а не качество. и за какво му е да гони вътрешни бъгове, били те в силикона или в софтуера? клиента ги вижда след като си купи изделието => прихода е реализиран. а и няма къде да мърда - всички правят недодялани пръчки, щото брата китаец не спи. и става все по-добър, щото вече само той бачка. у нас не знам дали ще се намери жив спец, който да може да направи чип от пластина. май и в щатите занаята замира...

аз лично не мога да реша кое е по-зле: да борим бъгави процесори по $2-3 или да ползваме изчистени (или най-много с 2 грешки) чипове по $10. :roll:


Сря Дек 26, 2007 1:56 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
Nikola Kirov написа:
Също там имаш малко каша с signed/unsigned.

в случая сигнед, унсигнед все тая, това са просто парчета памет които се копират, няма аритметични операции. по принцип знака има значение само за умножение и деление, при събиране и изваждане можеш да си ги месиш спокойно. но в случая това е малко встрани от темата, понеже бъга е на съвсем друга основа. впрочем аз си излязох от ситуацията сравнително лесно - написах volatile пред буферната променлива и работата заспа :)


Сря Дек 26, 2007 3:09 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
ДедоБоре написа:

аз лично не мога да реша кое е по-зле: да борим бъгави процесори по $2-3 или да ползваме изчистени (или най-много с 2 грешки) чипове по $10. :roll:

разни анализатори посочват че една от причините германия да загуби ВВ2 (разбира се след огромното числено превъзходство на врага) е че германците твърде много са наблягали на качеството на техниката. правиш перфектен танк, без чепаци по дръжките, всичко пасва, квадратна планка може да бъде завъртяна на деведесе градуса, и отворите за винтовете пак пасват (нещо невъзможно за бг) и какво - отива на бойното поле и го трошат след седмица. за какво да правят качествени процесори, след като ще се ползват за мигане на коледни лампички?
а и правенето на качествени работи не е лесно. хората си мислят че с много тестове и труд може качеството да се докара на 100% почти. е, големите фирми го правят, но това не пречи колите да гаснат насред пътя заради блокирал процесор. в мазните фирми като джонсън например, се бачка точно бавно и солидно, с тестване и бюрокрация, 50 души правят един индикатор за бензин да речем. и какво, нямат бъгове ли? реконструктора да каже, той е бачкал там :)


Сря Дек 26, 2007 3:18 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 27, 2005 12:48 pm
Мнения: 6094
Мнение 
пробвах - изглежда наред (дори махна call Test)
http://tntm.eu/wiz/test.jpg
оптимизация S
C30 v3.00

PS
в часност ползвах TMR2 и 3 ( за ReadRSDWord() и Test() ) щото oптимизацията за прост тест ми маха излишния код

_________________
main[-1u]={1};


Последна промяна TheWizard на Сря Дек 26, 2007 4:47 pm, променена общо 2 пъти



Сря Дек 26, 2007 4:26 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Окт 31, 2004 9:19 pm
Мнения: 4464
Местоположение: Stara Zagora
Мнение 
zaphod написа:
Nikola Kirov написа:
Също там имаш малко каша с signed/unsigned.

в случая сигнед, унсигнед все тая, това са просто парчета памет които се копират, няма аритметични операции. по принцип знака има значение само за умножение и деление, при събиране и изваждане можеш да си ги месиш спокойно. но в случая това е малко встрани от темата, понеже бъга е на съвсем друга основа. впрочем аз си излязох от ситуацията сравнително лесно - написах volatile пред буферната променлива и работата заспа :)


Знам че би трябвало да е все тая но примитивните компилатори се дънят някой път и заради такива неща.
Както казах за да спиш спокойно трябва да се обяснява като на малоумник.
А volatile е грубо решение за случая.


Сря Дек 26, 2007 4:33 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
@киров, просто от любопитство пробвах със строго кастване, както ти предложи, резултата е тоя който очаквах - не е от типовете, бъга остава. а volatile е точно правилното решение, понеже това му е смисъла - отказ от оптимизация. в случая дори не премахва оптимизацията (понеже такава в няма), кода със него остава същия, просто се появява изпуснатата инструкция mov.w 0x0000,[0x001e-2].
@TheWizard това което си пробвал няма много общо с това което съм пуснал като код. както виждаш компилатора не прави извикване на ReadRSWord, a замества директно, но май пак е объркал струва ми се :)


Сря Дек 26, 2007 5:28 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 27, 2005 12:48 pm
Мнения: 6094
Мнение 
unsigned long ReadRSDWord() не съм ти я променял - копирах е от тук

ReadRSWord() чете таймер
Test() записва в таймер
а двата таймера са глобални

_________________
main[-1u]={1};


Сря Дек 26, 2007 5:37 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
верно че не си я променял, гледал съм друго парче код, а после си промених поста :)
както и да е, при тебе компилатора е инлайннал ReadRSWord, пробвай да я напишаш да смята нещо, за да го накараш да я вика, и пробвай с изчислим резултат, таймера не го знаеш какво трябва да върне.
обърни внимание обаче на кода който се е генерирал при тебе:
Изображение
как мислиш, мене ми изглежда даже още по-бъгав отколкото при мене е станало. аз получавам поне младшите 16 бита правилни, а при тебе струва ми се целия резултат е напълно случаен (забравил е не само съхранението на старшата дума, а на двете думи), но ти нали четеш таймера и няма как да го усетиш. :)


Сря Дек 26, 2007 5:38 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 27, 2005 12:48 pm
Мнения: 6094
Мнение 
ами при мен си бачка
rcall ReadRSDWord
mov.d w0,w8 (и w9 запазва си резултата) W0W1 -> W8W9
rcall ReadRSDWord
mov.d w0,w10 (и w11 запазва си резултата) W0W1 -> W10W11

http://tntm.eu/wiz/test2.jpg
http://tntm.eu/wiz/test3.jpg

незнам как да направя проекта за да изглежда като твоя

_________________
main[-1u]={1};


Сря Дек 26, 2007 6:01 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юли 24, 2005 10:28 am
Мнения: 2658
Мнение 
не бе човек, гледай кода на функцията ReadRSDWord. ти понеже си я викал два пъти и аз в началото си помислих че тоя код при тебе е кода във функцията, после видях че това не е така и си коригирах поста. на картинката от предния ти пост ясно се вижда кода на функцията ReadRSDWord.
тая картинка я изрязах от твоята
Изображение
това е кода на твоята функция ReadRSDWord и макар да не е като моя код (заради инлайнването), също е бъгав.
ако искаш да постигнеш съвсем същия ефект, предлагам ти следната функция на мястото на ReadRSWord:
Код:
int F1()
{
   int i;
   for(i=0;i<5;i++)DM=DM+i;
   return DM;
}

пробвах я, компилатора не я инлайнва, бъга се получава точно същия, ползвай глобална променлива DM, на първото викане функцията трябва да върне 10, на второто 20, следователно резултата от ReadRSDWord трябва да е 0x0014000a
а вместо това ще получиш хххх000а
финално ето ти кода за пробване:


Код:
int F1()
{
   int i;
   for(i=0;i<5;i++)DM=DM+i;
   return DM;
}

unsigned long int  ReadRSDWord()
{
   int dw[2];
   dw[0]=F1();
   dw[1]=F1();
   return *((unsigned long*)dw);   
}

................................
ASSERT(ReadRSDWord()==0x0014000a);/// тука ползвай каквото искаш за проверка



Сря Дек 26, 2007 6:39 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
zaphod написа:
TheWizard написа:
пасни кода да пробвам на мойто С30...


Код:
unsigned long  ReadRSDWord()
{
   int dw[2];
   dw[0]=ReadRSWord();
   dw[1]=ReadRSWord();
   return *((unsigned long*)dw);   
}

това е кода на С, пробвай го, функцията ReadRSWord си сложи някаква която връща инт (16 битов).
оптимизатора е на ниво s, на други нива не съм пробвал, без оптимизация се компилира правилно. що се отнася за това къде е бъга - аз не пиша от вчера и знам че компилатор току така не се обвинява. :)


Правилно, компилатор току-така не се обвинява ;-)

Преди всичко редно би било да се обърнеш към съпорта, но доста верятно ще те отсвирят веднага щото кодът ти е некоректен.
Вероятно изхождаш от навика как съответния процесор разполага променливите, обаче не бива да забравяш че все пак пишеш на С и комполатора очаква да спазваш някой от С-стандартите.
Така ти може да очакваш че два елемента на един масив ще са разположени един до друг, но според стандартите нямаш право да го очакваш освен ако не задал съответните атрибути за packed и align. Без тях, компилаторът е в правото си да ги разположи както намери за добре и последващ typecast да не работи както очакваш.
Що се отнася до самия typecast, по стандарт нямаш право да надхвърляш размера на обекта който преобразуваш. Тук и компилатора е за е@ане че не ти дава warning. Ако някога пробваш GCC ще видиш какво се казва компилатор и как на 100 ред С-код може да получиш 200 warninga при все че на други компилатори може да нямаш нито един ;-)
Въпреки че има начини да поддтиснеш или заобиколиш warning-те, аз не те съветвам да го правиш, защото проблемът си остава - четейки извън размера на първия елемет, компилаторът няма как да знае а и не му е работа да знае че четеш и втория. И е съвсем нормално да сметне че стойността му не се използва.
Идеята на Никола за union също е много неправилна. Аз лично съм си патил от подобни тарикатщини. Проблемите както казах идват при платформи при които packed и allign имат значение и тогава става малка каша. В такива случаи елементите на union (както и структури) не бива да са с размер по-малък от sizeof(int) иначе няма оправия.

В случая обаче решението е много просто - значи не бива да имаш typecast от малък към голям, обаче за обратното няма проблем, т.е вместо горния код може:

Код:
unsigned long  ReadRSDWord()
{
   unsigned long dw;
   ((unsigned int*)&dw)[0]=ReadRSWord();
   ((unsigned int*)&dw)[1]=ReadRSWord();
   return dw;   
}


Сря Дек 26, 2007 7:20 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 29 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни