DEV Community

Avelyn Hyunjeong Choi
Avelyn Hyunjeong Choi

Posted on • Edited on

Project Stage2 - Part I

1.Obtain the autoifunc proof-of-conccept code
tar xvf /public/spo600-autoifunc-preprocessor-pos.tgz

[hchoi72@israel autoifunc-preprocessor-poc]$ ll
total 56
-rw-r--r--. 1 hchoi72 hchoi72   212 Nov  8 09:59 adjust_channels.h
-rw-r--r--. 1 hchoi72 hchoi72  1310 Nov  8 09:59 function.c
-rw-r--r--. 1 hchoi72 hchoi72   197 Nov  8 09:59 function.h
-rw-r--r--. 1 hchoi72 hchoi72 18092 Nov  8 09:59 LICENSE
-rw-r--r--. 1 hchoi72 hchoi72  2448 Nov  8 09:59 main.c
-rw-r--r--. 1 hchoi72 hchoi72   941 Nov  8 10:42 Makefile
-rw-------. 1 hchoi72 hchoi72     0 Nov  8 09:59 nohup.out
-rw-r--r--. 1 hchoi72 hchoi72   571 Nov  8 10:17 README.md
drwxr-xr-x. 2 hchoi72 hchoi72  4096 Nov  8 10:11 scripts
drwxr-xr-x. 2 hchoi72 hchoi72  4096 Nov  8 09:59 tar
drwxr-xr-x. 4 hchoi72 hchoi72  4096 Nov  8 09:59 tests
Enter fullscreen mode Exit fullscreen mode

2.Build the code
$ make
After building the code, function_ifunc.c is generated.

[hchoi72@israel autoifunc-preprocessor-poc]$ ll
total 788
...
-rw-r--r--. 1 hchoi72 hchoi72   3224 Nov  8 13:22 function_ifunc.c
...
Enter fullscreen mode Exit fullscreen mode

Compilation
gcc function.c -o function
gcc function_ifunc.c -o function_ifunc
./function
./function_ifunc

Resolver function
adjust_channels__resolver

  • determines which version of adjust_channels function will be used based on the architecture
  • checks if SVE is supported. If it does, it returns a pointer to adjust_channels__sve. If it doesn't, it returns a pointer to adjust_channels__asimd

Two different copies of adjust_channels function
1.SVE Implementation - adjust_channels__sve

  • uses Scalable Vector Extension instructions

2.ASIMD Implementation - adjust_channels__asimd

  • uses advanced SIMD instructions

Pragma statements
#pragma GCC target "arch=armv8-a+sve"
#pragma GCC target "arch=armv8-a"

  • specifies which architecture to be used for the compilation
  • first pragma will use armv8-a+sve and second pragma will use armv8-a

Indirect function prototype
void adjust_channels(unsigned char *image,int x_size,int y_size,float red_factor,float green_factor,float blue_factor) **__attribute__(( ifunc("adjust_channels__resolver"))**);

  • attributes specifies function implementation is going to be resolved at runtime depending on the result of adjust_channels__resolver

3.Add the compiler option -fdump-tree-gimple
gcc function.c -o function -fdump-tree-gimple
gcc function_ifunc.c -o function_ifunc -fdump-tree-gimple

-> generate output files with the extension .gimple in the same directory. Output files contain the gimple representation of the code.

[hchoi72@israel autoifunc-preprocessor-poc]$ ll
total 120
...
-rw-r--r--. 1 hchoi72 hchoi72  2026 Nov  8 14:09 function.c.006t.gimple
...
-rw-r--r--. 1 hchoi72 hchoi72  5337 Nov  8 14:09 function_ifunc.c.006t.gimple
...
Enter fullscreen mode Exit fullscreen mode

4.GIMPLE
what is GIMPLE?

  • stands for GCC Intermediate Representation
  • simplified version of code, which makes the code easier to analyze and manipulate for optimization

Examine function_ifunc.c.006t.gimple

Are there any differences between the SVE and ASIMD versions of the function?

  • adjust_channels__sve vs adjust_channels__asimd
  • Main difference: How it performs the calculations
  • Overall structure and logic are very similar

Has autovectorization been applied to the code at this poing in the compilation process?

  • autovectorization: compiler optimization technique by automatically transforming code into SIMD code using vectorized instruction
  • since autovectorization happens at later stage of compilation process, it is not very clear whether autovectorization has been applied

How do you know then?

  • check whether compiler flags are following: -02, -03 or -ftree-vectorize., etc
  • check if -fopt-infoflag was specified in an optimization report
  • check out the assembly code to see whether any SIMD instructions are used

How are the #pragma lines in the source file reflected in the gimple?
#pragma GCC target "arch=armv8-a+sve"

  • reflected as __attribute__((target ("arch=armv8-a+sve"))) in the gimple
  • it's applied to function like void adjust_channels__sve() or main() as these functions are intneded for the ARMv8-A architecture with SVE

#pragma GCC target "arch=armv8-a"

  • reflected as __attribute__((target ("arch=armv8-a+sve", "arch=armv8-a"))) in the gimple

5.Steps to transform the gimple representation of function.c into the gimple represenation of function_ifunc.c

Main difference between function.c.006t.gimple vs
function_ifunc.c.006t.gimple

  • use SVE instruction in function.c.006t.gimple
  • use indirect function and both SVE and ASIMD instruction in function_ifunc.c.006t.gimple

Steps

  • include headers #include <sys/auxv.h>
  • add indirect function declaration in function.c

before

void adjust_channels(unsigned char *image, int x_size, int y_size,float red_factor, float green_factor, float blue_factor);
Enter fullscreen mode Exit fullscreen mode

after

void adjust_channels(unsigned char *image,int x_size,int y_size,float red_factor,float green_factor,float blue_factor) __attribute__(( ifunc("adjust_channels__resolver")));
Enter fullscreen mode Exit fullscreen mode
  • add Ifunc resolver function, which decides which version of adjust_channels to be used
static void (*adjust_channels__resolver(void)) {
        long hwcaps  = getauxval(AT_HWCAP);
        long hwcaps2 = getauxval(AT_HWCAP2);


        if (hwcaps & HWCAP_SVE) {
                return adjust_channels__sve;
        } else {
                return adjust_channels__asimd;
        }
};
Enter fullscreen mode Exit fullscreen mode

Top comments (0)