Linuxbaserade processorsystem VS FreeRTOS
Re: Linuxbaserade processorsystem VS FreeRTOS
Nej det blir samma sak.
Så här menar jag:
*pA = A * B;
pa++;
istället för
pA = A * B;
i++;
Sen kanske optimering i kompilator löser det ändå
Så här menar jag:
*pA = A * B;
pa++;
istället för
pA = A * B;
i++;
Sen kanske optimering i kompilator löser det ändå
Re: Linuxbaserade processorsystem VS FreeRTOS
Så här mycket data blir det om man ska använda YALE databasen. Notera att jag använder hela bilderna. Ett ansikte är ca 200x200 och bilden i sig är 320x243.
Ett problem som jag har är att det är float. Jag vet inte om det blir så mycket snabbare med int jämfört med float om man har en FPU.
Låt oss säga att vi har våran modell (2158 + 1010880 + 166)*8*0.001 = 8105.632 kB (FLASH)
Sedan tar vi ett kort med en kamera och kortet är 320x243. Med Fisherfaces så blir detta 13*166*8*0.001 = 17.6 kB extra i minne (RAM).
Varför just 13 och 166? Jo, för kortet subtraheras mot P matrisen och dom måste ha samma antal rader och kolumner. Så här verkar det som att jag kommer under 1 Mb i flash.
Så här ser matematiken ut för att använda fisherfaces.
Där P, y, W är matriserna och k är själva intrimningsparameter. Man bara sätter den till ett värde t.ex. 10 så fixar allt sig. 4 går bra också. minBild är själva din bild som du tog med kameran.
Variabeln c som retunerar tillbaka är själva numret på vilken ID som din bild har. ID:erna finns i y matrisen. Dom börjar alltid på 0 och slutar på antalet tagna samplingar t.ex. 200. Så får man t.ex. c = 4 så betyder det att minBild har ID 4.
I detta fall så kan man göra om raden
Till
För att spara minne. MinBild är ändå en lång vektor av en bild. T.ex om A = minBild.
Ett problem som jag har är att det är float. Jag vet inte om det blir så mycket snabbare med int jämfört med float om man har en FPU.
Låt oss säga att vi har våran modell (2158 + 1010880 + 166)*8*0.001 = 8105.632 kB (FLASH)
Sedan tar vi ett kort med en kamera och kortet är 320x243. Med Fisherfaces så blir detta 13*166*8*0.001 = 17.6 kB extra i minne (RAM).
Varför just 13 och 166? Jo, för kortet subtraheras mot P matrisen och dom måste ha samma antal rader och kolumner. Så här verkar det som att jag kommer under 1 Mb i flash.
Så här ser matematiken ut för att använda fisherfaces.
Kod: Markera allt
function c = FisherFaces(P, y, W, k, minBild)
Q = W' * MinBild;
Q = repmat(Q, 1, size(P, 2));
distances = sqrt(sum(power((P-Q),2),1));
[distances, idx] = sort(distances);
y = y(idx);
y = y(1:k);
h = histc(y,(1:max(y)));
[v,c] = max(h);
Variabeln c som retunerar tillbaka är själva numret på vilken ID som din bild har. ID:erna finns i y matrisen. Dom börjar alltid på 0 och slutar på antalet tagna samplingar t.ex. 200. Så får man t.ex. c = 4 så betyder det att minBild har ID 4.
I detta fall så kan man göra om raden
Kod: Markera allt
Q = W' * MinBild;
Kod: Markera allt
Q = W * MinBild;
Kod: Markera allt
>> A = randn(6, 3)
A =
-0.404922 -1.328983 0.665497
1.136456 1.501415 -1.822033
0.119473 1.305189 -1.019424
-1.178401 1.607036 0.165585
-0.043936 0.505411 -0.512376
-0.037154 -2.029305 2.034998
>> A = reshape(A, 6*3, 1)
A =
-0.404922
1.136456
0.119473
-1.178401
-0.043936
-0.037154
-1.328983
1.501415
1.305189
1.607036
0.505411
-2.029305
0.665497
-1.822033
-1.019424
0.165585
-0.512376
2.034998
>>
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Senast redigerad av DanielM 31 juli 2020, 15:04:24, redigerad totalt 2 gånger.
Re: Linuxbaserade processorsystem VS FreeRTOS
Typ så här?
Kod: Markera allt
void mul(float* A, float* B, float* C, int row_a, int column_a, int column_b) {
// Data matrix
float* data_a;
float* data_b;
for (int i = 0; i < row_a; i++) {
// Then we go through every column of b
for (int j = 0; j < column_b; j++) {
data_a = &A[i * column_a];
data_b = &B[j];
*C = 0; // Reset
// And we multiply rows from a with columns of b
for (int k = 0; k < column_a; k++) {
*C += *data_a * *data_b;
data_a++;
data_b += column_b;
}
C++;
}
}
}
Re: Linuxbaserade processorsystem VS FreeRTOS
Ja fast jag hade nog velat bli av med forloopen också:
du kanske får fixa till endpoint, har inte testat om det kompilerar, men du förstår principen.
Kod: Markera allt
void mul(float* A, float* B, float* C, int row_a, int column_a, int column_b) {
// Data matrix
float* data_a;
float* data_b;
float* endPoint;
for (int i = 0; i < row_a; i++) {
// Then we go through every column of b
for (int j = 0; j < column_b; j++) {
data_a = &A[i * column_a];
data_b = &B[j];
endPoint = data_a + column_a;
*C = 0; // Reset
// And we multiply rows from a with columns of b
while (data_a < endPoint) {
*C += *data_a * *data_b;
data_a++;
data_b += column_b;
}
C++;
}
}
}
Re: Linuxbaserade processorsystem VS FreeRTOS
Och hur skulle man kunna bli av med for-loopen?
Jag har testat denna kod. Den fungerar.
Låt oss säga så här: Om jag hade en statisk matrix B och en vektor X och dom båda har konstant storlek - alltid. Skulle det fungera om man multiplicerade så här?
Då slipper man for-loopen. Men denna idé är kanske dålig?
Edit:
Dumt förslag. Jag ser nu att STM32 kan bara utföra en operation i assembler åt gången. Jag vet dock inte hur många operationer STM32 kan utföra per sekund.
Jag har testat denna kod. Den fungerar.
Låt oss säga så här: Om jag hade en statisk matrix B och en vektor X och dom båda har konstant storlek - alltid. Skulle det fungera om man multiplicerade så här?
Kod: Markera allt
B(0,0)*X(0) + B(0,1)*X(1) + B(0,2)*X(2) + ... + B(0,n)*X(n) // Allt på en enda rad
B(1,0)*X(0) + B(1,1)*X(1) + B(1,2)*X(2) + ... + B(1,n)*X(n)
......
B(m,0)*X(0) + B(m,1)*X(1) + B(m,2)*X(2) + ... + B(m,n)*X(n)
Edit:
Dumt förslag. Jag ser nu att STM32 kan bara utföra en operation i assembler åt gången. Jag vet dock inte hur många operationer STM32 kan utföra per sekund.
Re: Linuxbaserade processorsystem VS FreeRTOS
Nu hittade jag. CMSIS DSP verkar finnas till STM32. Äsh då! Den kräver att man ska initialisera matriserna. Vill ju köra statiska matriser.
Det blir nog så att jag får skriva C kod som är anpassad just för det jag ska göra plus att jag får låta kompilatorn optimera istället.
Det blir nog så att jag får skriva C kod som är anpassad just för det jag ska göra plus att jag får låta kompilatorn optimera istället.
Re: Linuxbaserade processorsystem VS FreeRTOS
YOLO är ju skrivet i C (i ramverket Darknet). Sedan finns det mängder av andra objektdetekteringsnät, YOLO är bara ett exempel.En annan nackdel är att YOLO modeller (modeller som innehåller detektion) verkar inte fungera med CubeMX AI Detektion är ju det som är viktigaste.
Re: Linuxbaserade processorsystem VS FreeRTOS
Jo. Det vet jag. Men bara för att det är skrivet i C, betyder inte att det passar på alla plattformar. Dessutom så kräver YOLO mycket kraft av GPU för att det ska bli riktigt bra.
Jag tänkte bara börja med att få bildigenkänning att fungera till att börja med. Alltså en bild och sedan ska man få ett resultat. Där efter så kanske man kan titta lite på YOLO för att kunna få en enkel detektion.
Vad är snabbast här?
Eller
Jag tänkte bara börja med att få bildigenkänning att fungera till att börja med. Alltså en bild och sedan ska man få ett resultat. Där efter så kanske man kan titta lite på YOLO för att kunna få en enkel detektion.
Vad är snabbast här?
Kod: Markera allt
*Q = *P - q; // Substract
*Q = *Q * *Q; // Power^2
Kod: Markera allt
*Q = (*P - q)*(*P - q); // Substract -> Power^2
Re: Linuxbaserade processorsystem VS FreeRTOS
Du får kolla assembler. Detta borde funka:
arm-none-eabi-objdump -d test.o >test.o.lst
https://www.google.com/amp/s/mcuoneclip ... lipse/amp/
arm-none-eabi-objdump -d test.o >test.o.lst
https://www.google.com/amp/s/mcuoneclip ... lipse/amp/
Re: Linuxbaserade processorsystem VS FreeRTOS
Jag börjar bli klar med min C-kodgenering snart. Men jag har några frågor.
Hur återställer jag arrayernas position?
Frågor:
1. Om jag anropar funktionen mull med static const W. Behöver jag då återställa W efter jag har kört klart funktionen?
2. Hur återställer jag Q till sin ordinarie position?
3. Är det mer värt att P++ istället för P[j]?
4. Hur skulle du göra?
Hur återställer jag arrayernas position?
Kod: Markera allt
// matris W gånger med vektor P till matris Q, som tolkas som en vektor.
void mul (float W[], uint8_t P[], float Q[]){
for(uint16_t i = 0; i < W_ROWS; i++){
*Q = 0;
for(uint32_t j = 0; j < W_COLUMNS; j++){
*Q += *W * P[j]; // P är kolumvektor med raderna W_COLUMNS
W++;
}
Q =+ Q_COLUMNS; // Q har inte samma antal kolumner som W
}
}
1. Om jag anropar funktionen mull med static const W. Behöver jag då återställa W efter jag har kört klart funktionen?
2. Hur återställer jag Q till sin ordinarie position?
3. Är det mer värt att P++ istället för P[j]?
4. Hur skulle du göra?
Re: Linuxbaserade processorsystem VS FreeRTOS
Eller var det tvärt om Rätta mig om jag har fel, men jag vill minnas att Darknet kan kompileras utan dependencies och utan GPUstöd.Men bara för att det är skrivet i C, betyder inte att det passar på alla plattformar.
Re: Linuxbaserade processorsystem VS FreeRTOS
Alla vet att Java är bäst. Bara kolla upp nya GraalVM. Vem sade att man inte kan köra Java där man inte för köra det?
Hur som helst så är jag klar med min C-kod generering. Nu så gör jag bildidentifiering på 5 ms per bild. Utan optimering!
Men hör och häpna! När jag optimerar, så hamnar jag på 1 ms per bildidentifering. Men då fungerar inte bildidentifieringen, absolut inget! Den visar bara fel hela tiden. Men skiter jag i optimeringen så fungerar allt glasklart! Men det blir 5 ms per bildidentifiering. Jag måste få detta fungera att min kod skall kunna optimeras.
Hur som helst så är jag klar med min C-kod generering. Nu så gör jag bildidentifiering på 5 ms per bild. Utan optimering!
Men hör och häpna! När jag optimerar, så hamnar jag på 1 ms per bildidentifering. Men då fungerar inte bildidentifieringen, absolut inget! Den visar bara fel hela tiden. Men skiter jag i optimeringen så fungerar allt glasklart! Men det blir 5 ms per bildidentifiering. Jag måste få detta fungera att min kod skall kunna optimeras.
Senast redigerad av DanielM 2 augusti 2020, 18:56:20, redigerad totalt 1 gång.
Re: Linuxbaserade processorsystem VS FreeRTOS
DanielM skrev: ↑1 augusti 2020, 18:08:20 Jag börjar bli klar med min C-kodgenering snart. Men jag har några frågor.
Hur återställer jag arrayernas position?
Frågor:Kod: Markera allt
// matris W gånger med vektor P till matris Q, som tolkas som en vektor. void mul (float W[], uint8_t P[], float Q[]){ for(uint16_t i = 0; i < W_ROWS; i++){ *Q = 0; for(uint32_t j = 0; j < W_COLUMNS; j++){ *Q += *W * P[j]; // P är kolumvektor med raderna W_COLUMNS W++; } Q =+ Q_COLUMNS; // Q har inte samma antal kolumner som W } }
1. Om jag anropar funktionen mull med static const W. Behöver jag då återställa W efter jag har kört klart funktionen?
2. Hur återställer jag Q till sin ordinarie position?
3. Är det mer värt att P++ istället för P[j]?
4. Hur skulle du göra?
Har du testat att kompilera koden?
1. Nej.
2. Varför?
3. Beror på kompilatorn, du får testa vilket som är mest ekonomiskt i ditt specifika fall.
Re: Linuxbaserade processorsystem VS FreeRTOS
2. Sätt en pekare på originalvärdetFrågor:
1. Om jag anropar funktionen mull med static const W. Behöver jag då återställa W efter jag har kört klart funktionen?
2. Hur återställer jag Q till sin ordinarie position?
3. Är det mer värt att P++ istället för P[j]?
4. Hur skulle du göra?
3. Ja borde vara snabbare, men som sagt kompilator kanske fixar det andra snabbare.
4. Jag hade kört P++
Är det optimering O3 som inte funkar? Testa O2, O1 och se om de funkar.
Annars får du ta funktion för funktion och jämföra vilken som ger skillnad med/utan optimering.
Det spontant som brukar skilja vid optimeringar är variabler som ändras i interupt (använd volatile) och icke initierade variabler.