Weer eens 'C' salade...

Op 1 augustus 2018 21:53:30 schreef maartenbakker:
Dat is inderdaad een heel belangrijke reden voor optimalisatie.

Verder denk ik dat optimalisatie op snelheid en geheugengebruik toch ook niet onbelangrijk is. Niet om die laatste 2 klokcycli uit een niet al te vaak aangeroepen routine te persen, maar wel om die 5000 klokcycli in een veel bezochte routine terug te brengen naar 800 ofzo. Dat zou een flink stuk meehelpen in de bedienbaarheid van bijvoorbeeld televisies. Het is niet voor niets dat ik begrepen heb dat TP Vision zijn slechte reputatie op dat gebied zat is en daar geen Indianen (en cowboys dan waarschijnlijk) meer voor wil inzetten maar gewoon Nederlanders en Belgen (ik kan er een paar landen naastzitten en het staat niet in steen gebeiteld, maar dat is wat ik er van meekreeg).

Niet alleen TP Vision (nooit van gehoord...). Bijna alle commerciele software is dramatisch slecht. En dat niet omdat ze te weinig optimalisatie doen, dat is omdat ze niet kunnen programmeren. Optimalisatie doe je op het niveau van algoritmes en daar snappen ze nou juist niks van. Maar het omzetten van C code naar assembly, dat is de taak van de compiler. Heel af en toe heb je iets timing-kritisch, daar maak je dan een paar regels inline assembly voor, maar liever niet.

Een mooi voorbeeld van "niet kunnen programmeren": we weten inmiddels dat diverse commerciele (dure!) software pakketten niet met een SQL database kunnen omgaan. Men trekt de hele tabel uit de database en gaat daar dan in de eigen software operaties op doen. Dat is dé manier om je database en je server onderuit te trekken en dat gaat al bij een betrekkelijke kleine database spelen.

Op 1 augustus 2018 22:48:08 schreef Arco:
Ook niet altijd de ingebakken libraries gebruiken als die onnodig groot zijn t.o.v. van wat ze doen...
De standaard PPS (peripheral pin select) libraryroutine bij de MikroE PIC24F compilers bijv. is onnodig uitgebreid en kost bijna 2k aan geheugen.
Een zelfgeschreven routine doet 't in 57 bytes... ;)

Floating point library kan inderdaad ook behoorlijk zijn, maar soms kom je er niet altijd omheen...

De SDK van Espressif (ESP8266,ESP32)... :-(

Die gasten kunnen echt niet programmeren. Vijf levels van #defines om een GPIO pin aan te spreken, terwijl het uiteindelijk gewoon een memory mapped I/O read of write is. Ja, die code gebruik ik dus zoveel mogelijk niet. Een library moet wel GOED zijn, qua code die er uit komt en hoe het gemaakt is.

Op 1 augustus 2018 22:25:18 schreef Arco:
Optimalisatie is ook een kwestie van je verstand gebruiken. Altijd zoveel mogelijk 'native' variabelen gebruiken.
Bij 8 bits: bytes, bij 16 bits: words, bij 32 bits: dwords. Voorkomt al een hoop (onnodige) overhead...

Dat is niet echt helemaal de (over-)optmalisatie die ik bedoel, die je moet vermijden. Een goed passende variabele (zowel type als grootte) helpt voor de leesbaarheid van het programma en helpt de compiler.

Maar let op: het is niet altijd het beste om de kleinst mogelijke int te gebruiken. RISC32 processors (zoals de ESP8266) hebben geen specifieke 8- of 16-buts bewerkingen. Het optellen van twee 32 bits waardes kan in 1 instructie, maar het optellen van 8 of 16 bits waardes kost meer instructies, omdat het resultaat ge"truncated" moet worden. Vuistregel is altijd gewoon "int" of "unsigned int" gebruiken, tenzij het om grote arrays gaat, dan wel grootte minimaliseren. Heb je heel specifiek een bepaald aantal bits nodig om te voldoen aan een bepaalde memory layout, dan kun je beter een struct gebruiken met bitfields.

geheugen lezen en schrijven op adressen die niet deelbaar zijn door de native bitlengte (dus bijvoorbeeld een byte op een oneven adres bij een 16- of 32-bit processor) kan relatief kostbaar zijn. Floating point berekeningen waar je ook met integers weg kunt komen, zeker op processors zonder floating point hardware, en delingen die overbodig zijn (waar je bijvoorbeeld kunt bitshiften, maar de compiler niet voldoende informatie heeft om dat automatisch te doen) kosten ook veel cycles.

En dat zijn juist daarom exact dingen die je aan de compiler moet overlaten, die weet precies wat wel en niet kan (en wel of niet slim is) op de bepaalde architectuur.

Maar de compiler mensen zondigen ook tegen de regels van de standaard.

De standaard zegt: een int is een variabele waar de CPU lekker mee werkt. Maar op een AVR krijg je dan 16 bits als ik het goed heb, terwijl dat 8-bit ding daar toch niet zomaar lekker mee werkt.

En omdat het ding nogal niet-2018 memory-cramped is. zit iedereen 8 bit variabelen te gebruiken zodat je inefficiente code krijgt als je de boel port naar een CPU die wel lekker werkt met 32 bits en moet klooien om met een 8-bit ding te werken.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
maartenbakker

Golden Member

Op 4 augustus 2018 10:50:04 schreef Erik Slagter:
[...]
Niet alleen TP Vision (nooit van gehoord...). Bijna alle commerciele software is dramatisch slecht. En dat niet omdat ze te weinig optimalisatie doen, dat is omdat ze niet kunnen programmeren. Optimalisatie doe je op het niveau van algoritmes en daar snappen ze nou juist niks van. Maar het omzetten van C code naar assembly, dat is de taak van de compiler. Heel af en toe heb je iets timing-kritisch, daar maak je dan een paar regels inline assembly voor, maar liever niet.

Voor PC-applicatiesoftware (niet het OS) gaat jouw schrijven wel op omdat je dan na de eerste optimalisatie (algoritme) kunt stoppen omdat er ruim voldoende resources zijn. Embedded software in een consumentenproduct stelt andere eisen omdat daar de goedkoopst mogelijke hardware gebruikt moet worden. Als je 10.000 keer een dubbeltje bespaart, kan een programmeur voor 1000 euro aan uren maken voor optimalisatie en elk extra verkocht exemplaar levert 10 cent extra winst op. Ik weet niet waar ze in India de fout ingaan, maar het zou zomaar kunnen dat zowel de algoritmes als de implementatie niet zo lekker zijn.

www.elba-elektro.nl | "The mind is a funny thing. Sometimes it needs a good whack on the side of the head to jar things loose."
Arco

Special Member

't Allemaal een kwestie van geld... ;)
OS/2 van IBM was in assembly en ongeveer 5x zo snel als Windows in C. Maar onderhoud assembly is complex (en dus duur), daarom C...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Ik heb begin jaren negentig aan een project gewerkt wat mij overgedragen is "in assembly".

Er waren ongeveer 10 verschillende proces stappen, en bijna allemaal was de assembly 10x sneller dan de C code. Maar het was "realtime": Als de resultaten niet binenn 40ms beschikbaar waren, dan hoefde het al niet meer.

Wat /ik/ heb opgeleverd was 9 routines in C, en 1 in assembly. Die 9 kostten bij mekaar zo de helft van de beschikbare 40ms. Die ene in assembly zo'n 15, samen 35 van de 40 beschikbare ms: Deadline gehaald no problem.

Die 20ms van wat ik in C had, had ook in assembly gekund. Dan had het maar 2-3ms hoeven duren. Maar dat was dus NIET nodig om de deadline te halen. DUS moet je dat niet doen.

Het zou me niets verbazen dat iets dergelijks bij OS2 heeft meegespeeld: Te veel in assembly, niet alleen de dingen die er toe doen. Gevolg: Niet te onderhouden code met een ondergang tot gevolg.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Arco

Special Member

Cross-platform compatibiliteit bij Windows speelde ook mee. (In C kon men Windows eenvoudiger compileren voor gebruik op bijv. de Alpha-DEC)
Speelt nu niet erg meer, want Alpha-DEC support is bij de komst van Windows 2000 al weer ten grave gedragen... ;)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Maar het wordt weer relevant: Ondanks dat er nog maar een paar processorvarianten over zijn, komen er steeds meer geluiden dat windows mogelijk in de toekomst ook op ARM gaat draaien.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
maartenbakker

Golden Member

@Erik Slagter: vergeten te melden, maar databasemanipulaties in code doen inplaats van in SQL is inderdaad een heel domme fout waar je wel vaker van hoort. Een variant daarvan is om een query naar een enkel record in een loop te doen inplaats van de database het zoekwerk te laten doen.

TP Vision is het dochterbedrijf van TPV dat de merknaam Philips in licentie heeft voor televisies. Softwareontwikkeling in India was een erfenis van Philips.

[Bericht gewijzigd door maartenbakker op zaterdag 4 augustus 2018 15:31:39 (22%)

www.elba-elektro.nl | "The mind is a funny thing. Sometimes it needs a good whack on the side of the head to jar things loose."
Arco

Special Member

maar databasemanipulaties in code doen inplaats van in SQL is inderdaad een heel domme fout

Dacht je dat SQL dan geen 'manipulatie in code' was?... :) (alleen doe je het dan niet zelf...)
Ik denk dat SQL zelfs meestal trager is dan een zelfgemaakte datasearch.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

En zo ontstaan die gedrochten dus...

Als dat zo is, deugt je database ontwerp niet. De truc is dat je je database zodanig geïndexeerd hebt dat die acties juist snel gaan. Daarbij lijkt me toch duidelijk dat een complete database (die meerdere GB groot kan zijn) over een netwerk sturen, terwijl je maar 1 record van minder dan 1kb wilde hebben, niet bepaald efficiënt is. Daarbij zijn dergelijke database servers geoptimaliseerd om op meerdere cores tegelijk te kunnen werken; hoe goed is jouw multi-core voodoo?

Bij een goed ontworpen systeem is de front-end onafhankelijk van de ontwerp van de database; je hoeft daar helemaal niets te weten van de tabellen en relaties, en dat wil je ook helemaal niet op die plaats. Je wilt vragen stellen aan de database server (middels stored-procedure calls), en daar antwoorden op krijgen. Hoe de data over verschillende tabellen verdeeld is, boeit niet, en bij gevolg kan dat ook veranderen zonder dat de front-end aangepast hoeft te worden.

[Bericht gewijzigd door SparkyGSX op zaterdag 4 augustus 2018 16:43:22 (32%)

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
maartenbakker

Golden Member

Ook als de complexiteit van de database niet zo groot is en je het zonder stored procedures af kan of dat te lastig vindt, is een goed gestelde query in principe sneller dan een search in eigen code (al zijn daar ook wel verschillende graden van inefficiency mogelijk - een query in een loop zoals ik noemde is een nog grotere zonde dan de hele database eenmalig inladen en dan pas gaan loopen).

[Bericht gewijzigd door maartenbakker op zaterdag 4 augustus 2018 18:59:24 (19%)

www.elba-elektro.nl | "The mind is a funny thing. Sometimes it needs a good whack on the side of the head to jar things loose."

Op 4 augustus 2018 15:34:39 schreef Arco:
[...]
Dacht je dat SQL dan geen 'manipulatie in code' was?... :) (alleen doe je het dan niet zelf...)
Ik denk dat SQL zelfs meestal trager is dan een zelfgemaakte datasearch.

Even voor de goede orde Sparky en ik hebben het over een database waarbij je bijvoorbeeld:

code:

select * from mytable where recordid = 1234; 

had kunnen doen maar in plaats daarvan iets van:

select * from mytable

en dan b.v. in php

code:

   $result = mysql_query ("select * from mytable"); 
   while ($row = mysql_fetch_row (result)) 
     if ($row ["recordid"] != 1234) continue;

doet....

Nu is dit weer het ALLER simpelste voorbeeld waarbij iedereen die meer dan een dag met SQL heeft gewerkt de betere manier zal weten, maar in de praktijk zijn er veel te vaak dit soort situaties waarbij je VEEL beter de select juist kan schrijven ipv die loop in je eigen programmeertaal. Of het over het netwerk moet of niet, de database WEET dat jij op zoek bent naar "recordid=1234". Laat nu die gasten die experts zijn in "databases" uitzoeken hoe je dat het snelst kunt doen.

Met een goed database ontwerp en de juiste vlaggetjes op de tabel, kan het daaarna NOG een factor 1000 sneller, als je die "recordid" als primary key opgeeft. Dan moet een database dat in 10-20ms kunnen ophoesten, terwijl 1Gb aan database doorsjouwen toch op z'n minst 10 seconden gaat duren (100Mb per seconde).

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Precies! En bedenk nu eens wat er gebeurd als je aan de hand van de naam van een klant zijn klantnummer wilt hebben (klanten tabel), daarmee de laatste order wilt opzoeken (order tabel), en de details (orderregel tabel INNER JOIN product gegevens tabel).

Dat kan in 1 query in een paar milliseconden gebeurd zijn. Zelf doen? Succes...

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
big_fat_mama

Zie Paulinha_B

Een van mijn vroegste professionele ervaringen kwam precies daarop neer:
applicatie draaide zeer netjes in dev- en test-omgeving maar was hopeloos traag in productie. Wat bleek?
* niet-productieve omgevingen draaiden op een subset van de prod-database
* applicatie begon bij iedere raadpleging met een "SELECT *" en filterde dan zelf de gewenste info uit het resultaat

2001 of daaromtrent, Fonsnylaan, Sint Gillis :) om geen namen te noemen ...

hoe beter de vraag geschreven, zoveel te meer kans op goed antwoord