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

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

Mucit23

Selamlar

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

Kod Seç
   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.
Kod Seç
void read_color(uint8_t clmuint8_t rowuint8_t *rbitsuint8_t *gbitsuint8_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
Kod Seç
      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.
Kod Seç

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.
חור השטן יוצא

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.
חור השטן יוצא

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

Kod Seç

void read_color
(uint8_t clmuint8_t rowuint8_t *rbitsuint8_t *gbitsuint8_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;
}



Kod Seç

void read_color
(uint8_t clmuint8_t rowuint8_t *rbitsuint8_t *gbitsuint8_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:

Kod Seç

void read_color
(uint8_t clmuint8_t rowuint8_t *rbitsuint8_t *gbitsuint8_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