Compilers that translate the human readable program into the instructions that will execute on the processor or coprocessor can be directed to look at parts of the application and create optimized and vectorizable code.
A main challenge for developers is to design and implement applications that so that as many of the loops as possible are vectorizable by the compiler, automatically. The many ways to implement an algorithm in different forms and the flexibility of the programming language can together act to make it difficult, if not impossible for a compiler to automatically generate vectorizable code. Pointers in some languages can make it extremely difficult to recognize if a loop is vectorizable in the eyes of the compiler. Other languages do not depend on pointers as much, which can make it easier to vectorize some loops.
Directives can be used as hints to the compiler to vectorize a loop. The developer would have better knowledge of any dependencies that a compiler, which must adhere to a number of rules when deciding if a loop can be vectorized. Directives force the compiler to vectorize, based on the knowledge of the developer, thus, if something does not work correctly, it is the responsibility of the developer to fix it, rather than blame the compiler.
A popular directive is the #pragma simd one. This gives the compiler permission to vectorize the following loop in the code, as the developer is certain there are not dependencies that matter. This can be implemented in either FORTRAN or C/C++ applications. The compiler that is being used to compile the application should (modern ones are) be able to handle pragmas correctly, as the developer wishes. In many cases, the compiler will transform the code into chunks, whose size will depend on the vector width of the target machine.
By having compiler directives available for vectorization, developers who understand their application can create code that can take advantage of modern vector units and newly designed coprocessors.
Source: Intel, USA