[Beignet] [PATCH V2 1/6] Add register allocate from tail support for constant buffer.

Zhigang Gong zhigang.gong at linux.intel.com
Thu Apr 18 18:26:42 PDT 2013


LGTM, Thx.

> -----Original Message-----
> From:
> beignet-bounces+zhigang.gong=linux.intel.com at lists.freedesktop.org
> [mailto:beignet-bounces+zhigang.gong=linux.intel.com at lists.freedesktop.
> org] On Behalf Of Yang Rong
> Sent: Thursday, April 18, 2013 3:18 PM
> To: beignet at lists.freedesktop.org
> Cc: Yang Rong
> Subject: [Beignet] [PATCH V2 1/6] Add register allocate from tail support
> for constant buffer.
> 
> By default curbe alloc from head, grf alloc from tail.
> 
> Signed-off-by: Yang Rong <rong.r.yang at intel.com>
> ---
>  backend/src/backend/context.cpp |  188
> ++++++++++++++++++++++-----------------
>  1 file changed, 107 insertions(+), 81 deletions(-)
> 
> diff --git a/backend/src/backend/context.cpp
> b/backend/src/backend/context.cpp index 180e8bb..c3ddb59 100644
> --- a/backend/src/backend/context.cpp
> +++ b/backend/src/backend/context.cpp
> @@ -1,4 +1,4 @@
> -/*
> +/*
>   * Copyright © 2012 Intel Corporation
>   *
>   * This library is free software; you can redistribute it and/or @@ -53,7
> +53,7 @@ namespace gbe
>       *  the hardware. Note that we always use the left most block when
>       *  allocating, so it makes sense for constant pushing
>       */
> -    int16_t allocate(int16_t size, int16_t alignment);
> +    int16_t allocate(int16_t size, int16_t alignment, bool bFwd=0);
> 
>      /*! Free the given register file piece */
>      void deallocate(int16_t offset);
> @@ -75,8 +75,9 @@ namespace gbe
>       *  If the colascing was done, the left block is deleted
>       */
>      void coalesce(Block *left, Block *right);
> -    /*! Head of the free list */
> +    /*! Head and tail of the free list */
>      Block *head;
> +    Block *tail;
>      /*! Handle free list element allocation */
>      DECL_POOL(Block, blockPool);
>      /*! Track allocated memory blocks <offset, size> */ @@ -89,10
> +90,10 @@ namespace gbe
>      // r0 is always set by the HW and used at the end by EOT
>      const int16_t offset = GEN_REG_SIZE;
>      const int16_t size = RegisterFileSize  - offset;
> -    head = this->newBlock(offset, size);
> +    tail = head = this->newBlock(offset, size);
>    }
> 
> -  RegisterFilePartitioner::~RegisterFilePartitioner(void) {
> +  RegisterFilePartitioner::~RegisterFilePartitioner(void) {
>      while (this->head) {
>        Block *next = this->head->next;
>        this->deleteBlock(this->head);
> @@ -100,80 +101,104 @@ namespace gbe
>      }
>    }
> 
> -  int16_t RegisterFilePartitioner::allocate(int16_t size, int16_t alignment)
> +  int16_t RegisterFilePartitioner::allocate(int16_t size, int16_t
> + alignment, bool bFwd)
>    {
>      // Make it simple and just use the first block we find
> -    Block *list = head;
> +    Block *list = bFwd ? head : tail;
>      while (list) {
> -      const int16_t aligned = ALIGN(list->offset, alignment);
> -      const int16_t spaceOnLeft = aligned - list->offset;
> -      const int16_t spaceOnRight = list->size - size - spaceOnLeft;
> +      int16_t aligned;
> +      int16_t spaceOnLeft;
> +      int16_t spaceOnRight;
> +      if(bFwd) {
> +        aligned = ALIGN(list->offset, alignment);
> +        spaceOnLeft = aligned - list->offset;
> +        spaceOnRight = list->size - size - spaceOnLeft;
> 
>        // Not enough space in this block
> -      if (spaceOnRight < 0) {
> -        list = list->next;
> -        continue;
> +        if (spaceOnRight < 0) {
> +          list = list->next;
> +          continue;
> +        }
> +      } else {
> +        aligned = ALIGN(list->offset+list->size-size-(alignment-1),
> alignment);   //alloc from block's tail
> +        spaceOnLeft = aligned - list->offset;
> +        spaceOnRight = list->size - size - spaceOnLeft;
> +
> +        // Not enough space in this block
> +        if (spaceOnLeft < 0) {
> +          list = list->prev;
> +          continue;
> +        }
>        }
> +
>        // Cool we can use this block
> -      else {
> -        Block *left = list->prev;
> -        Block *right = list->next;
> -
> -        // If we left a hole on the left, create a new block
> -        if (spaceOnLeft) {
> -          Block *newBlock = this->newBlock(list->offset, spaceOnLeft);
> -          if (left) {
> -            left->next = newBlock;
> -            newBlock->prev = left;
> -          }
> -          if (right) {
> -            newBlock->next = right;
> -            right->prev = newBlock;
> -          }
> -          left = newBlock;
> +      Block *left = list->prev;
> +      Block *right = list->next;
> +
> +      // If we left a hole on the left, create a new block
> +      if (spaceOnLeft) {
> +        Block *newBlock = this->newBlock(list->offset, spaceOnLeft);
> +        if (left) {
> +          left->next = newBlock;
> +          newBlock->prev = left;
>          }
> -
> -        // If we left a hole on the right, create a new block as well
> -        if (spaceOnRight) {
> -          Block *newBlock = this->newBlock(aligned + size,
> spaceOnRight);
> -          if (left) {
> -            left->next = newBlock;
> -            newBlock->prev = left;
> -          }
> -          if (right) {
> -            right->prev = newBlock;
> -            newBlock->next = right;
> -          }
> -          right = newBlock;
> +        if (right) {
> +          newBlock->next = right;
> +          right->prev = newBlock;
>          }
> +        left = newBlock;
> +      }
> 
> -        // Chain both successors and predecessors when the entire
> block was
> -        // allocated
> -        if (spaceOnLeft == 0 && spaceOnRight == 0) {
> -          if (left) left->next = right;
> -          if (right) right->prev = left;
> +      // If we left a hole on the right, create a new block as well
> +      if (spaceOnRight) {
> +        Block *newBlock = this->newBlock(aligned + size,
> spaceOnRight);
> +        if (left) {
> +          left->next = newBlock;
> +          newBlock->prev = left;
>          }
> -
> -        // Update the head of the free blocks
> -        if (list == head) {
> -          if (left)
> -            head = left;
> -          else if (right)
> -            head = right;
> -          else
> -            head = NULL;
> +        if (right) {
> +          right->prev = newBlock;
> +          newBlock->next = right;
>          }
> +        right = newBlock;
> +      }
> 
> -        // Free the block and check the consistency
> -        this->deleteBlock(list);
> -        if (head && head->next) GBE_ASSERT(head->next->prev ==
> head);
> +      // Chain both successors and predecessors when the entire block
> was
> +      // allocated
> +      if (spaceOnLeft == 0 && spaceOnRight == 0) {
> +        if (left) left->next = right;
> +        if (right) right->prev = left;
> +      }
> 
> -        // Track the allocation to retrieve the size later
> -        allocatedBlocks.insert(std::make_pair(aligned, size));
> +      // Update the head of the free blocks
> +      if (list == head) {
> +        if (left)
> +          head = left;
> +        else if (right)
> +          head = right;
> +        else
> +          head = NULL;
> +      }
> 
> -        // We have a valid offset now
> -        return aligned;
> +      // Update the tail of the free blocks
> +      if (list == tail) {
> +        if (right)
> +          tail = right;
> +        else if (left)
> +          tail = left;
> +        else
> +          tail = NULL;
>        }
> +      // Free the block and check the consistency
> +      this->deleteBlock(list);
> +      if (head && head->next) GBE_ASSERT(head->next->prev == head);
> +      if (tail && tail->prev) GBE_ASSERT(tail->prev->next == tail);
> +
> +      // Track the allocation to retrieve the size later
> +      allocatedBlocks.insert(std::make_pair(aligned, size));
> +
> +      // We have a valid offset now
> +      return aligned;
>      }
>      return 0;
>    }
> @@ -186,34 +211,35 @@ namespace gbe
>      const int16_t size = it->second;
> 
>      // Find the two blocks where to insert the new block
> -    Block *list = head, *prev = NULL;
> +    Block *list = tail, *next = NULL;
>      while (list != NULL) {
> -      if (list->offset > offset)
> +      if (list->offset < offset)
>          break;
> -      prev = list;
> -      list = list->next;
> +      next = list;
> +      list = list->prev;
>      }
> 
>      // Create the block and insert it
>      Block *newBlock = this->newBlock(offset, size);
> -    if (prev) {
> -      GBE_ASSERT(prev->offset + prev->size <= offset);
> -      prev->next = newBlock;
> -      newBlock->prev = prev;
> +    if (list) {
> +      GBE_ASSERT(list->offset + list->size <= offset);
> +      list->next = newBlock;
> +      newBlock->prev = list;
>      } else
> -      this->head = newBlock;  // prev is NULL means newBlock should
> be the head.
> +      this->head = newBlock;  // list is NULL means newBlock should be
> the head.
> 
> -    if (list) {
> -      GBE_ASSERT(offset + size <= list->offset);
> -      list->prev = newBlock;
> -      newBlock->next = list;
> -    }
> +    if (next) {
> +      GBE_ASSERT(offset + size <= next->offset);
> +      next->prev = newBlock;
> +      newBlock->next = next;
> +    } else
> +      this->tail = newBlock;  // next is NULL means newBlock should be
> the tail.
> 
> -    if (prev != NULL || list != NULL)
> +    if (list != NULL || next != NULL)
>      {
>        // Coalesce the blocks if possible
> -      this->coalesce(prev, newBlock);
> -      this->coalesce(newBlock, list);
> +      this->coalesce(list, newBlock);
> +      this->coalesce(newBlock, next);
>      }
> 
>      // Do not track this allocation anymore @@ -297,7 +323,7 @@
> namespace gbe
>                                uint32_t alignment)
>    {
>      alignment = alignment == 0 ? size : alignment;
> -    const uint32_t offset = partitioner->allocate(size, alignment);
> +    const uint32_t offset = partitioner->allocate(size, alignment, 1);
>      GBE_ASSERT(offset >= GEN_REG_SIZE);
>      kernel->patches.push_back(PatchInfo(value, subValue, offset -
> GEN_REG_SIZE));
>      kernel->curbeSize = std::max(kernel->curbeSize, offset + size -
> GEN_REG_SIZE);
> --
> 1.7.9.5
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet



More information about the Beignet mailing list