Fall 2023 SPO600 Project

From CDOT Wiki
Jump to: navigation, search

This page describes the SPO600 project in the Fall 2023 semester.

Overview

The autovectorizer in gcc (and other compilers, such as llvm/clang) has become very good -- to the point that it is automatically enabled at optimization level -O2 (standard optimization level) in recent versions of gcc.

However, there are many different implementations of SIMD instructions on various CPUs -- on 64-bit Arm systems, there's Advanced SIMD, SVE, and SVE2; on x86, there's SSE, SSE2, AVX, AVX512, and more. It is desirable to be able to build a single binary that takes optimal advantage of the available CPU capabilities.

There is a facility provided by the gcc compiler to allow the run-time selection of one of several different implementations of a function (or procedure or method or subroutine): ifunc. However, ifunc requires additional setup by the software developer.

The goal for this project is to investigate how the proof-of-concept work performed in a previous semester could be incorporated into the GCC compiler. This will eventually enable the compiler to take code that meets specific conditions and automatically build it with ifunc capability to select between multiple, autovectorized versions of a function, to take advantage of the best SIMD implementation available on the CPU on which the code is running.

Project Stages

Stage 1

In this stage, you will build the GCC compiler to become familiar with using and building the source code.

What is required:

  • Obtain the source code for the current development version of GCC from the Git repository
  • Build the source code to produce a working compiler on each of two environments:
    1. An x86_64 system. You may use your own system, or the SPO600 server Portugal
    2. An AArch64 system. You may use your own system, or the SPO600 server Israel
  • Ensure that you are building with an object tree outside of the source tree (see documentation for details)
  • Blog about the experience, including the procedure you used, the time taken to perform the build, the impact of -jN options, and how you have proven that you have a working compiler.

Recommended:

  • Study and become familiar with the general structure of the code (how it is organized) - specifically, find the C/C++ compilers within the collection and examine how the files and directories are laid out, and become familiar with the coding standards used.

Due: Sunday, October 29, 11:59 pm

Mark: 15%

Stage 2

In this stage, you will (1) examine the intermediate code output of the compiler and (2) propose a design for how the automatic ifunc capability could operate from the user's point of view.

What is required: Part I: Experiment with the Proof-of-Concept Automatic ifunc Tool and the Intermediate Representation (in Gimple) Produced by the GCC Compiler

  1. Obtain the autoifunc proof-of-conccept code from the file /public/spo600-autoifunc-preprocessor-pos.tgz on israel.cdot.systems and unpack it on an aarch64 machine (e.g., on Israel, execute: cd ; tar xvf /public/spo600-autoifunc-preprocessor-pos.tgz ). This will unpack into ~/spo600/autoifunc-preprocessor-poc/
  2. Build the code. Make sure that you understand what the script scripts/autoifunc program is doing -- compare the output of function.c and function_ifunc.c and identify the resolver function, the two different copies of the adjust_channels function, the pragma statements, and the indirect function prototype.
  3. Add the compiler option -fdump-tree-gimple and rebuild the code. This will produce additional output files with the extension .gimple
  4. Research what gimple is, and examine the the gimple file for the function_ifunc.c source file. Identify:
    1. Are there any differences between the SVE and ASIMD versions of the function?
    2. Has autovectorization been applied to the code at this poing in the compilation process? How do you know?
    3. How are the #pragma lines in the source file reflected in the gimple?
  5. Figure out what would be required to transform the gimple representation of function.c into the gimple represenation of function_ifunc.c
  6. Blog in detail about your investigation and what you have discovered

Part II: Design

  1. Design how an automatic ifunc implementation within the GCC compiler could work from the user's point of view.
    1. What options should the user specify on the command line to indicate that they want automatic ifunc capability to be applied during the compilation? How should the user specify the list of architecture variants they want to target? (e.g., a base architecture of "armv8-a" and extended architectures of "armv8-a+sve" and "armv8-a+sve2", or a similar list of architecture variants for other platforms).
    2. What constraints need to be applied to the list of architecture variants? (i.e., how do we figure out if the architecture variants can be combined into a sane executable)?
    3. To which functions should the automatic ifunc capability be added? Should the user specify the functions to be affected? If so, how? (What should the source code syntax look like?) If the functions should be selected automatically, what should the selection criteria be? And should the user be able to tune the selection criteria, and if so, how (what should the command-line option syntax look like)?
    4. What diagnostics should be produced during the compilation process?
  2. Make sure that these options are consistent with the current design of GCC (i.e., they will make sense to existing GCC users)
  3. Explain your design decisions in detail, clearly presenting the case for each decision and why you feel it's the best option.

Due: Sunday, November 26, 11:59 pm

Mark: 20%


Resources