A ke zpracování signálů na jednom řádku - mezi zpracování signálů se dá započítat třeba FIR filtr 1. řádu u ADC na potlačení šumu.
Třeba derivační článek xn+1 = 7/8*xn + 1/8*a se napíše v C v přerušení 12b ADC takto:
volatile uint16_t x = 0;
void ADC_ISR(void) {
x = ((x << 3) - x + ADC_VALUE) >> 3;
}
Třeba u ARMu s barrel shifterem je to velice efektivní metoda. Jenom vědět, jak na to bez násobení a floatů.
Python nedělám, ale pokud by chtěl stejně filtrovat data, tak princip bude pořád stejný. A taky se to asi vejde na jednu lajnu...
v Pythonu na běžném procesoru je IMHO
x = (x*7 + ADC_VALUE)//8
stejně rychlé a je to přesnější přepis toho vzorce. Snáz se to čte.
A to, že je to stejně rychlý, jsi vzal kde? Na (8x-x) potřebuješ jeden shift o tři bity (u ARMu barrel shifter) a jeden rozdíl. To jsou dvě instrukce a stačí ti dva registry CPU. Pro násobení sedmi potřebuješ 3x shift o 1b a 3x součet a pravděpodobně si to vezme i jeden registr procesoru navíc. Takže samotná operace, pokud to kompilátor nepřevede na 8x-x, je 3x pomalejší. A pokud to vezme jako obecný násobení 16x16->32 bez HW násobičky, tak je to dokonce 16x pomalejší. Ve zpracování v časově kritickým přerušení nebo na větším objemu dat je to sakra poznat.
Kolega jednou dělal něco v C# na x86_64 a použil knihovní funkce. Přechrchlání dat za cca 2,5 minuty.
Vyhodil knihovní funkce, použil vnitřek (s floatama) přímo. Stáhl to na 80s.
Přešel na integer, byl na 20s.
Po úpravě konstant tak, aby to byly mocniny dvojky nebo maximálně dvě jedničky v konstantě (kompilátor mohl používat shifty) se dostal na 3,5s.