Picproje Elektronik Sitesi

SERBEST BÖLGE => Programlama ve Algoritma => Konuyu başlatan: Mucit23 - 20 Nisan 2017, 16:23:33

Başlık: Bu yapıyı nasıl hızlandırabilirim.
Gönderen: Mucit23 - 20 Nisan 2017, 16:23:33
Selamlar

PSoC'da C ile çalışırken uygulamış olduğum bir kod parçası var.

   for(clm=0;clm<32;clm++)
   {
      read_color(clm,row, &red_bits[0], &green_bits[0], &blue_bits[0]);
      disp_data[clm]=(((blue_bits[1]>>bitmask)*32)& 0x20)|(((green_bits[1]>>bitmask)*16)&0x10)|(((red_bits[1]>>bitmask)*8)& 0x08);
      disp_data[clm]|=(((blue_bits[0]>>bitmask)*4)& 0x04)|(((green_bits[0]>>bitmask)*2)&0x02)|((red_bits[0]>>bitmask)& 0x01);
      HUB_Write(disp_data[clm]);
      CLK_Write(1);CLK_Write(0);   
   }


Bu kodum 64Mhz de çalışan Psoc için yaklaşık olarak 80uS sürüyor. Yaptığım işlem şudur.

16x32 boyutlarında bir Ram alanım var. Satır ve sütün indexlerine göre read_color fonksiyonu içerisinde ilgili bölümleri red_bits, green_bits ve blue_bits değişkenlerine alıyorum


Fonksiyonun içeriği aşağıdaki gibi.
void read_color(uint8_t clm, uint8_t row, uint8_t *rbits, uint8_t *gbits, uint8_t *bbits)
{
   rbits[0]=(display_ram[clm][row]>>8)&0x000F;
   gbits[0]=(display_ram[clm][row]>>4)&0x000F;
   bbits[0]=display_ram[clm][row]&0x000F;
   rbits[1]=(display_ram[clm][row+8]>>8)&0x000F;
   gbits[1]=(display_ram[clm][row+8]>>4)&0x000F;
   bbits[1]=display_ram[clm][row+8]&0x000F;
}


Daha sonra 4 bitten oluşan bu renk datalarının bitmask değişkeni ile belirlediğim bitlerini disp_data değişkenine alt alta dizip Dışarıya vermem gerekiyor.
Tabi C'de yapılabilecekler biraz sınırlı. Optimizasyon konusunda biraz tavsiye almak istiyorum. Bunun dışında PSoC'ların içerisinde FPGA benzeri yapılar var. Orada verilog ile paralel işlem yapmam mümkün. 
Yarın aşağıdaki kod parçasını PGA ile yapmaya çalışacağım
      disp_data[clm]=(((blue_bits[1]>>bitmask)*32)& 0x20)|(((green_bits[1]>>bitmask)*16)&0x10)|(((red_bits[1]>>bitmask)*8)& 0x08);
      disp_data[clm]|=(((blue_bits[0]>>bitmask)*4)& 0x04)|(((green_bits[0]>>bitmask)*2)&0x02)|((red_bits[0]>>bitmask)& 0x01);
      HUB_Write(disp_data[clm]);
      CLK_Write(1);CLK_Write(0);   


Bunun dışında başka nasıl optimizasyonlar uygulanabilir?
Başlık: Ynt: Bu yapıyı nasıl hızlandırabilirim.
Gönderen: kenan_re - 21 Nisan 2017, 12:11:11
DMA diyecem ama maskelemeler var. Taşımaları DMA üzerinden maskelemeleri kodla devam et mesela :)
Başlık: Ynt: Bu yapıyı nasıl hızlandırabilirim.
Gönderen: Mucit23 - 21 Nisan 2017, 12:16:09
Hocam bu satırı komple Verilog'da FPGA ile yapabilirim diye düşünüyorum.

disp_data[clm]=(((blue_bits[1]>>bitmask)*32)& 0x20)|(((green_bits[1]>>bitmask)*16)&0x10)|(((red_bits[1]>>bitmask)*8)& 0x08);     
disp_data[clm]|=(((blue_bits[0]>>bitmask)*4)& 0x04)|(((green_bits[0]>>bitmask)*2)&0x02)|((red_bits[0]>>bitmask)& 0x01);     
HUB_Write(disp_data[clm]);
CLK_Write(1);CLK_Write(0);   

Öyle olsa tek clock'da çözülür. Ama asıl elimi ayağımı bağlıyan read_color fonksiyonu. Bu fonksiyon üzerinde neler yapılabilir onu düşünüyorum.
Başlık: Ynt: Bu yapıyı nasıl hızlandırabilirim.
Gönderen: Zoroaster - 21 Nisan 2017, 12:44:12
disp_data[clm]=(((blue_bits[1]>>bitmask)*32)& 0x20)|(((green_bits[1]>>bitmask)*16)&0x10)|(((red_bits[1]>>bitmask)*8)& 0x08);   

Eğer optimizasyon yukarıdaki satırı aşağıdakine çevirmeyip and işlemi yapıyorsa aşağıdaki kod biraz olsun işi hızlandırır.

disp_data[clm]=(((blue_bits[1]>>bitmask)*32))|(((green_bits[1]>>bitmask)*16))|(((red_bits[1]>>bitmask)*8));   

Eğer bitmask değerin sabit ise ve değerini bilirsek belki daha başka sadeleşme de yapılabilir.
Başlık: Ynt: Bu yapıyı nasıl hızlandırabilirim.
Gönderen: Mucit23 - 21 Nisan 2017, 14:09:01
Abi yok o maskelemeyi yapmak zorundayım. Çünkü maskelemeyi 0. bitten itibaren yapıyorum.  Bu işlemlerin hepsini verilog da yapabilirim diye düşünüyorum. Bu işlemleri FPGA ile yapabilirsem belkide 1-2 clock'da işlemler yapılır hepsi.


Başlık: Ynt: Bu yapıyı nasıl hızlandırabilirim.
Gönderen: Zoroaster - 21 Nisan 2017, 14:20:15
Cevabın bana ise verdiğim kod ile senin kod birbirine eşdeğer.
Başlık: Ynt: Bu yapıyı nasıl hızlandırabilirim.
Gönderen: Mucit23 - 21 Nisan 2017, 14:48:18
Yanlış çalışıyor ama abi  ???  Gerçekte denedim.


blue_bits, green_bits ve red_bits değerleri 4 bitlik değerler. bitmask değeri 0-3 arası değişiyor.


Bu 4 bitlik değerleri sıra ile 0. 1. 2. ve 3. bitlerini alıp disp_data'nın ilk 6 bitine yerleştiriyorum.


Hocam C'de Shift işlemi kaç clockda yapılır?
Başlık: Ynt: Bu yapıyı nasıl hızlandırabilirim.
Gönderen: RaMu - 21 Nisan 2017, 19:49:41

void read_color(uint8_t clm, uint8_t row, uint8_t *rbits, uint8_t *gbits, uint8_t *bbits)
{
   rbits[0]=(display_ram[clm][row]>>8)&0x000F;
   gbits[0]=(display_ram[clm][row]>>4)&0x000F;
   bbits[0]=display_ram[clm][row]&0x000F;
   rbits[1]=(display_ram[clm][row+8]>>8)&0x000F;
   gbits[1]=(display_ram[clm][row+8]>>4)&0x000F;
   bbits[1]=display_ram[clm][row+8]&0x000F;
}




void read_color(uint8_t clm, uint8_t row, uint8_t *rbits, uint8_t *gbits, uint8_t *bbits)
{
temp = display_ram[clm][row] ;
   rbits[0]=(temp >> 8) & 0x000F;
   gbits[0]=(temp >> 4) & 0x000F;
   bbits[0]=temp & 0x000F;
temp = display_ram[clm][row+8] ;
   rbits[1]=(temp >>8) & 0x000F;
   gbits[1]=(temp >>4) & 0x000F;
   bbits[1]=temp & 0x000F;
}


belki şöyle dahada hızlı çalışır:


void read_color(uint8_t clm, uint8_t row, uint8_t *rbits, uint8_t *gbits, uint8_t *bbits)
{
temp = display_ram[clm][row] ;
   bbits[0]=temp & 0x000F;
temp = (temp >> 4)
   gbits[0]= temp & 0x000F;
   rbits[0]=(temp >> 4) & 0x000F;

temp = display_ram[clm][row+8] ;
   bbits[1]=temp & 0x000F;
temp = (temp >> 4)
   gbits[1]=temp  & 0x000F;
   rbits[1]=(temp >>4) & 0x000F;
}



İşlemci 16 bit ise ve SWAP vede SWAP.B komutları varsa dahada optimize edilir.