[Beignet] [PATCH V2] GBE: try to avoid bank conflict in register allocator.
Matt Turner
mattst88 at gmail.com
Wed Apr 27 22:28:19 UTC 2016
On Wed, Apr 27, 2016 at 12:43 AM, Ruiling Song <ruiling.song at intel.com> wrote:
> v2:
> fix build error.
Some documentation or description about this would be very welcome. I
cannot honestly imagine anyone being able to review this without it,
and I think I know what this patch is doing. :)
Some questions I think your patch's commit message (as well as
comments in the code) should answer:
- What is a register bank?
- What is a register bank conflict?
- How are the register banks laid out? Does it differ per-generation
of hardware?
- What effect does a register bank conflict have? E.g., changes in
instruction issue rate, instruction latency, ability to co-issue.
- How does this patch attempt to avoid register bank conflicts?
- In practice, what effect does this patch have on register bank
conflicts? For instance, I might count the number of register bank
conflicts in a collection of programs before and after the patch to
demonstrate that it is effective.
> Signed-off-by: Ruiling Song <ruiling.song at intel.com>
> ---
> backend/src/backend/gen_reg_allocation.cpp | 31 ++++++++++++++++++++++++++++--
> 1 file changed, 29 insertions(+), 2 deletions(-)
>
> diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp
> index 89c53d4..ce07f8a 100644
> --- a/backend/src/backend/gen_reg_allocation.cpp
> +++ b/backend/src/backend/gen_reg_allocation.cpp
> @@ -35,6 +35,7 @@
> #include <iomanip>
>
>
> +#define HALF_REGISTER_FILE_OFFSET (32*64)
> namespace gbe
> {
> /////////////////////////////////////////////////////////////////////////////
> @@ -48,9 +49,10 @@ namespace gbe
> */
> struct GenRegInterval {
> INLINE GenRegInterval(ir::Register reg) :
> - reg(reg), minID(INT_MAX), maxID(-INT_MAX) {}
> + reg(reg), minID(INT_MAX), maxID(-INT_MAX), conflictReg(0) {}
> ir::Register reg; //!< (virtual) register of the interval
> int32_t minID, maxID; //!< Starting and ending points
> + ir::Register conflictReg; // < has banck conflict with this register
Typo: bank
> };
>
> typedef struct GenRegIntervalKey {
> @@ -1052,7 +1054,17 @@ namespace gbe
> // and the source is a scalar Dword. If that is the case, the byte register
> // must get 4byte alignment register offset.
> alignment = (alignment + 3) & ~3;
> - while ((grfOffset = ctx.allocate(size, alignment)) == 0) {
> +
> + bool direction = true;
> + if (interval.conflictReg != 0) {
> + // try to allocate conflict registers in top/bottom half.
> + if (RA.contains(interval.conflictReg)) {
> + if (RA.find(interval.conflictReg)->second < HALF_REGISTER_FILE_OFFSET) {
> + direction = false;
> + }
> + }
> + }
> + while ((grfOffset = ctx.allocate(size, alignment, direction)) == 0) {
> const bool success = this->expireGRF(interval);
> if (success == false) {
> if (spillAtInterval(interval, size, alignment) == false)
> @@ -1104,6 +1116,7 @@ namespace gbe
> for (auto &insn : block.insnList) {
> const uint32_t srcNum = insn.srcNum, dstNum = insn.dstNum;
> insn.ID = insnID;
> + bool is3SrcOp = insn.opcode == SEL_OP_MAD;
Does Beignet not use other 3-src opcodes? LRP, BFI2, BFE, CSEL? Of
course, MAD is the most important one.
More information about the Beignet
mailing list