#pragma block_loop

Category

Optimization and tuning

Purpose

Marks a block with a scope-unique identifier.

Syntax

Read syntax diagramSkip visual syntax diagram
                                            .-,----.      
                                            V      |      
>>-#--pragma--block_loop--(--expression--,----name-+--)--------><

Parameters

expression
An integer expression representing the size of the iteration group.
name
An identifier that is unique within the scoping unit. If you do not specify a name, blocking occurs on the first for loop or loop following the #pragma block_loop directive.

Usage

For loop blocking to occur, a #pragma block_loop directive must precede a for loop.

If you specify #pragma unroll, #pragma unrollandfuse or #pragma stream_unroll for a blocking loop, the blocking loop is unrolled, unrolled and fused or stream unrolled respectively, if the blocking loop is actually created. Otherwise, this directive has no effect.

If you specify #pragma unrollandfuse, #pragma unroll or #pragma stream_unroll directive for a blocked loop, the directive is applied to the blocked loop after the blocking loop is created. If the blocking loop is not created, this directive is applied to the loop intended for blocking, as if the corresponding #pragma block_loop directive was not specified.

You must not specify #pragma block_loop more than once, or combine the directive with #pragma nounroll, #pragma unroll, #pragma nounrollandfuse, #pragma unrollandfuse, or #pragma stream_unroll directives for the same for loop. Also, you should not apply more than one #pragma unroll directive to a single block loop directive.

Processing of all #pragma block_loop directives is always completed before performing any unrolling indicated by any of the unroll directives

Examples

The following two examples show the use of #pragma block_loop and #pragma loop_id for loop tiling:
#pragma block_loop(50, mymainloop)
#pragma block_loop(20, myfirstloop, mysecondloop)
#pragma loopid(mymainloop)
  for (i=0; i < n; i++)
  {
#pragma loopid(myfirstloop)
    for (j=0; j < m; j++)
    {
#pragma loopid(mysecondloop)
      for (k=0; k < m; k++)
      {
         ...
      }
    }
  }
#pragma block_loop(50, mymainloop)
#pragma block_loop(20, myfirstloop, mysecondloop)
#pragma loopid(mymainloop)
       for (i=0; i < n; n++)
       {
#pragma loopid(myfirstloop)
              for (j=0; j < m; j++)
              {
#pragma loopid(mysecondloop)
                     for (k=0; k < m; k++)
                     {
                            ...
                     }
              }
       }
The following example shows the use #pragma block_loop and #pragma loop_id for loop interchange.
       for (i=0; i < n; i++)
       {
              for (j=0; j < n; j++)
              {
#pragma block_loop(1,myloop1)
                     for (k=0; k < m; k++)
                     {
#pragma loopid(myloop1)
                            for (l=0; l < m; l++)
                            {
                                   ...
                            }
                     }
              }
       }
The following example shows the use of #pragma block_loop and #pragma loop_id for loop tiling for multi-level memory hierarchy:
 #pragma block_loop(l3factor, first_level_blocking)
   for (i=0; i < n; i++)
   {
 #pragma loopid(first_level_blocking)
 #pragma block_loop(l2factor, inner_space)
     for (j=0; j < n; j++)
     {
 #pragma loopid(inner_space)
       for (k=0; k < m; k++)
       {
         for (l=0; l < m; l++)
         {
           ...
         }
       }
     }
   }
The following example uses #pragma unrollandfuse and #pragma block_loop to unroll and fuse a blocking loop.
#pragma unrollandfuse
#pragma block_loop(10)
   for (i = 0; i < N; ++i) {
   }
In this case, if the block loop directive is ignored, the unroll directives have no effect.
The following example shows the use of #pragma unroll and #pragma block_loop to unroll a blocked loop.
 #pragma block_loop(10)
 #pragma unroll(2)
   for (i = 0; i < N; ++i) {
   }
In this case, if the block loop directive is ignored, the unblocked loop is still subjected to unrolling. If blocking does happen, the unroll directive is applied to the blocked loop.
The following examples show invalid uses of the directive. The first example shows #pragma block_loop used on an undefined loop identifier:
 #pragma block_loop(50, myloop)
   for (i=0; i < n; i++)
   {
   }
Referencing myloop is not allowed, since it is not in the nest and may not be defined.
In the following example, referencing myloop is not allowed, since it is not in the same loop nest:
   for (i=0; i < n; i++)
   {
 #pragma loopid(myLoop)
     for (j=0; j < i; j++)
     {
       ...
     }
   }
 #pragma block_loop(myLoop)
   for (i=0; i < n; i++)
   {
     ...
   }
The following examples are invalid since the unroll directives conflict with each other:
 #pragma unrollandfuse(5)
 #pragma unroll(2)
   #pragma block_loop(10)
              for (i = 0; i < N; ++i) {
          }
 #pragma block_loop(10)
 #pragma unroll(5)
 #pragma unroll(10)
   for (i = 0; i < N; ++i) {
   }

Related information