Linuxbaserade processorsystem VS FreeRTOS

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av DanielM »

Du menar *(A + i) istället för A[ I ] ?
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av Rick81 »

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å
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av DanielM »

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.

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);
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

Kod: Markera allt

Q = W' * MinBild;
Till

Kod: Markera allt

Q = W * MinBild;
För att spara minne. MinBild är ändå en lång vektor av en bild. T.ex om A = 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.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av DanielM »

Rick81 skrev: 31 juli 2020, 14:05:52 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å


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++; 
		}
	}
}
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av Rick81 »

Ja fast jag hade nog velat bli av med forloopen också:

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++; 
		}
	}
}
du kanske får fixa till endpoint, har inte testat om det kompilerar, men du förstår principen.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av DanielM »

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?

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)
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.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av DanielM »

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.
guckrum
Inlägg: 1686
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av guckrum »

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.
YOLO är ju skrivet i C (i ramverket Darknet). Sedan finns det mängder av andra objektdetekteringsnät, YOLO är bara ett exempel.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av DanielM »

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?

Kod: Markera allt

*Q = *P - q; // Substract
*Q = *Q * *Q; // Power^2
Eller

Kod: Markera allt

*Q = (*P - q)*(*P - q); // Substract -> Power^2
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av Rick81 »

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/
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av DanielM »

Jag börjar bli klar med min C-kodgenering snart. Men jag har några frågor.

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
      }
}
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?
guckrum
Inlägg: 1686
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av guckrum »

Men bara för att det är skrivet i C, betyder inte att det passar på alla plattformar.
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.
DanielM
Inlägg: 2189
Blev medlem: 5 september 2019, 14:19:58

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av DanielM »

Alla vet att Java är bäst. :D Bara kolla upp nya GraalVM. Vem sade att man inte kan köra Java där man inte för köra det? :roll:

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.
hummel
Inlägg: 2267
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av hummel »

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?

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
      }
}
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?

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.
Rick81
Inlägg: 746
Blev medlem: 30 december 2005, 13:07:09

Re: Linuxbaserade processorsystem VS FreeRTOS

Inlägg av Rick81 »

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?
2. Sätt en pekare på originalvärdet

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.
Skriv svar