Bu yapıyı nasıl hızlandırabilirim.

Başlatan Mucit23, 20 Nisan 2017, 16:23:33

Mucit23

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?

kenan_re

DMA diyecem ama maskelemeler var. Taşımaları DMA üzerinden maskelemeleri kodla devam et mesela :)

Mucit23

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.

Zoroaster

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.
Seytan deliginden kacti.

Mucit23

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.



Zoroaster

Cevabın bana ise verdiğim kod ile senin kod birbirine eşdeğer.
Seytan deliginden kacti.

Mucit23

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?

RaMu

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.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html