如何为嵌入式系统优化此图像复制功能

时间:2011-05-17 20:29:43

标签: c image optimization embedded

下面的函数使用read_page(pageIter,pageArr,PAGESIZE)一次读取一页图像,并在DOUT和CCLK引脚上输出数据。

我被告知它效率低下但我似乎无法找到让它更快的方法。它基本上是一个管道,在64针uProcessor上运行,位于两个存储空间之间。一个保持图像,另一个接收图像。

我使用了register关键字,删除了数组索引并替换为指针arithemetic,但它需要更快。

谢谢!

/*
Port C Pin Out
*/
#define     BIT0        0x01    // CCLK
#define     BIT1        0x02    // CS_B
#define     BIT2        0x04    // INIT_B
#define     BIT3        0x08    // PROG_B
#define     BIT4        0x10    // RDRW_B
#define     BIT5        0x20    // BUSY_OUT
#define     BIT6        0x40    // DONE
#define     BIT7        0x80    // DOUT (DIN)

/*
PAGE
*/

#define     PAGESIZE    1024    // Example

void copyImage(ulong startAddress, ulong endAddress)
  {
  ulong pageIter;
  uchar *eByte, *byteIter, pageArr[PAGESIZE];
  register uchar bitIter, portCvar;
  portCvar = PORTC;
  /* Loops through pages in an image using ulong type*/
  for(pageIter = startAddress ;  pageIter <= endAddress ; pageIter += PAGESIZE)
    {
    read_page(pageIter, pageArr, PAGESIZE);
    eByte = pageArr+PAGESIZE;
    /* Loops through bytes in a page using pointer to uchar (pointer to a byte)*/
    for(byteIter = pageArr; byteIter <= eByte; byteIter++)
      {
      /* Loops through bits in byte and writes to PORTC - DIN ANC CCLK  */
      for(bitIter = 0x01; bitIter != 0x00; bitIter = bitIter << 1)
        {
        PORTC = portCvar | BIT0;
        (bitIter & *byteIter) ? (PORTC = portCvar & ~BIT7) : (PORTC = portCvar | BIT7);
        PORTC = portCvar & ~BIT0;
        }
      }
    }
  }

4 个答案:

答案 0 :(得分:5)

你可以通过用

之类的东西展开每个字节的传输来加快速度
PORTC = clock_1; PORTC = (value & 0x01 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x02 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x04 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x08 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x10 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x20 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x40 ? data1 : data0); PORTC = clock_0;
PORTC = clock_1; PORTC = (value & 0x80 ? data1 : data0); PORTC = clock_0;

在图像循环外预计算一次

unsigned char clock_1 = portC | BIT0;
unsigned char clock_0 = portC & ~BIT0;
unsigned char data1 = portC | BIT7;
unsigned char data0 = portC & ~BIT7;

答案 1 :(得分:2)

/* Loops through bits in byte and writes to PORTC - DIN ANC CCLK  */
      for(bitIter = 0x01; bitIter <= 0x80; bitIter = bitIter << 1)
        {
    PORTC = portC | BIT0;
    (bitIter & byteIter) ? (PORTC = portC & ~BIT7) : (PORTC = portC | BIT7);
    PORTC = portC & ~BIT0;
    }

那个循环是关键。我会用生产优化标志编译它,然后查看反汇编。编译器可以执行各种聪明的操作,例如展开循环或简化循环条件。如果我不喜欢我在那里看到的东西,我会开始调整C代码,以帮助编译器找到一个很好的优化。如果事实证明这是不可能的,那么我可能会使用内联汇编来获得我想要的东西。

假设我们可以尽可能快地进行(并且循环中的延迟不考虑接收器的建立 - 保持时间),那么我希望将该循环降低到尽可能少的指令。你能同时设置BIT0和数据位还是在接收器上造成危险?如果可以,那将节省一两条指令。许多微优化将依赖于特定的指令集。如果数据有很多0或0xFF,则可以进行特殊的展开情况,其中数据位不会改变,BIT0会切换8次。您可以为单个nybble创建16个展开的案例,并为每个字节切换两次。

答案 2 :(得分:2)

/* Loops through bits in byte and writes to PORTC - DIN ANC CCLK  */
for(bitIter = 0x01; bitIter <= 0x80; bitIter = bitIter << 1)
{
    PORTC = portC | BIT0;
    (bitIter & byteIter) ? (PORTC = portC & ~BIT7) : (PORTC = portC | BIT7);
    PORTC = portC & ~BIT0;
}

首先,这个循环被打破了。 bitIteruchar(我假设是无符号的8位字符)。通过将其向左移动,它最终将获得预期最终迭代的值0x80。在下一班次之后,它将获得值0。

效率提高。根据体系结构,执行操作PORTC = PORTC | BIT0可能会导致单个位设置。但是,它也可能导致读取,在寄存器中设置一个位,以及存储。

如前所述,如果可能的话,尝试同时设置BIT0和BIT7(如果硬件允许的话)。

我会尝试类似的事情:

bitIter = 0x01;
do
{
  if (byteIter & bitIter)
  {
    PORTC = BIT0;
  }
  else
  {
    PORTC = (BIT0 | BIT7);
  }
  PORTC = 0;

  bitIter <<= 1;
} while (bitIter != 0x80);

通过使用do ... while循环,它将终止问题,你将在第一次迭代之前摆脱不必要的循环测试比较(除非你的编译器已经对它进行了优化)。

您可以尝试手动,第8次循环展开循环,每次一次。

答案 3 :(得分:1)

我假设当你输入这个函数时PORTC处于已知状态:即数据和时钟线为0? (或时钟低,数据高?)

如果这个假设是真的你甚至可以通过先设置value = ~(*byteIter);然后这样做8次来避免@ 6502答案中的条件:

 PORTC|=BIT0;PORTC|=(value<<7)&BIT7;PORTC&=~(BIT7|BIT0);value>>=1;

- 或者,如果Bit7开始为高 -

 PORTC|=(BIT7|BIT0);PORTC&=(~BIT7|(value<<7));PORTC&=~BIT0;value>>=1;

这里的优点是它避免了条件 - 这可能会严重破坏高流水线处理器的速度。