| Date | Description |
| 25-Sep-15 | Original posting |
| 7-Oct-15 | Added comment about specifying custom optimizations |
Your assignment is to optimize matrix multiplication to run on a single core of Bang. Your starting point is a an implementation that performs one level of cache blocking, along with a test harness for evaluating performance. This implementation will behavior poorly, and you will be able to make it go significantly faster. We have also provided a variant that invokes a heavily optimized matrix multiply routine, provided by the ATLAS library. This reference variant will enable you to assess performance goals. ATLAS will outperform most "home made" implementations. See the references at the end to learn more about useful optimizations.
The assignment includes a 2-3 page report, which is important part of the assignment. The requirements for your report are described later in this document.
All assignments will be turned in using UCSD's GitLab. The turnin procedure is described below in the section "Turning in your assignment". In this section, we'll go over how to set up your repository.
You must follow these steps to get the starter code and to get set up to do assignment 1.
Refer to the link below for instructions on how to obtain the starter code to get started on your assignment
A1 Git Instructions
Try to make your code go as fast as you can. In the spirit of friendly competition, post your performance results to the A1 Piazza Folder. We will post a summary of the class' results on-line.
Your grade will based on 4 factors: performance attained by your implementation; correctness, well-displayed results and comments and explanation and insight into how you realized your reported performance. In determining your grade for the assignment, explanations and insight will be emphasized somewhat more heavily than performance itself, unless there was little improvement in performance over the provided naive code.
dgemm-blocked.
While it is possible to reach nearly theoretical performance for certain inputs (ATLAS can realize 8 GFlops, where the peak for Bang's processors is 9.32 GFlops), performance will vary over the full range of inputs.
Specific report requirements. Your report must present certain measurements, but feel free to add others if they illuminate your understanding of high performance matrix multiplication on Kepler. Plot the speedup of your optimized algorithm against the provided naïve code for the values you selected to evaluate the naïve code.
We've provided you with starter code that implements the naive ijk algorithm and a single level blocked implementation that uses cache more efficiently. In addition, we've provided an implementation that uses an optimized version of the BLAS (provided by the ATLAS library, which is installed on Bang) to enable you to assess performance of your 2-level blocked implementation. This code has been installed in the UCSD GitLab repository:
https://git.ucsd.edu/cse260-fa15/pa1-provided
To build your code, use the provided Makefile, which sets up the appropriate flags for the compiler via an included "arch" file located in in $(PUB)/Arch Do not change the name of the target used in the Makefile nor add additional file names to the Makefile, as we'll be grading your assignment with our own Makefile.
If you'd like to experiment with custom compiler optimization settings (the default is -O3), you can do this by setting, on the command line, a Makefile variable called MY_OPT. For example, if you'd like to specify -O4 -fopenmp, you may do so in one of two ways:
make MY_OPT=-O4\ -fopenmp make MY_OPT="-O4 -fopenmp"
The effect of setting MY_OPT is to redefine the OPTIMIZATION macro in the Makefile (currently set to -O3). It follows that you may also define custom C pre-processor macros in a similar way:
make MY_OPT="-O4 -DFLAG"
Use a qlogin node when taking timings.
The provided code includes timer calls, which are based on
gettimeofday().
For any given combination of N and optimization, take at least 3 timings and report the minimum.
You'll notice that at the end of the run, you'll get two lines of output
as follows, which lists the input size -n,
the number of repetitions -r, the Gigaflop rate and running time, and the grind time (the running time divided by the product of N and the number of repetitions):
N Reps GF t_blas tg_blas @ 1024 50 2.23e+01 9.64e-02 8.97e-11
If you are doing several runs, you can quickly
search for the string "@ " (starting in column 1)
to extract the performance data from your job output files and process it for plotting (likely with a script).
Basic cache blocking, as explained in class, is a requisite first step but alone is not sufficient to reach even half the processor's peak performance. To improve performance still further, try non-square tiles. Another good optimization is to tile for registers: unroll innermost loops and use named variables to store copies of the matrices. The tiles will be small, limited by the number of registers (16x128 bit registers on the Nehalem, see the details in Michael Thomadakis' paper). Though you won't be able to reach ATLAS' performance without auto-tuning and SSE intrinsics, you will be able to see an improvement beyond basic blocking if you try the strategies described above. See Brian Van Straalen's notes on vectorizing with SSE intrinsics or Jim Demmel's Lecture slides, slides 61-71. There are additional References below.
Feel free to learn from the source code of state-of-art BLAS implementations such as GotoBLAS and of course ATLAS, which is installed on Bang. However, you should not reuse those codes in your submission.
If you are working on a desktop or a laptop, shut down all open applications. Do not run on a machine shared with other users, unless you are sure that no-one else is running at the time you conduct your runs. (Even then beware of daemons and other system activities that can affect your results) If the timings are inconsistent across runs, other activities are occupying the processor and must be stopped.
When you have completed the assignment, you must submit it. You will do this by pushing your changes to GitLab. Follow these steps (which are more or less the same as the steps from the "pushing changes to GitLab" section above:
Some of the finer points about this process:
Even though we will be substituting fresh copies of all but one source module, include all code files your worked with, in case we need to unravel a problem with your turnin. For this reason, also include your Makefile.
Your turnin must also fill in two important documents, which accompany the provided code. These documents are required and we will not report a grade for your assignment without them. A 10% penalty will be assessed in cases of missing forms, empty forms, or forms not properly filled out.
This file must have the following format.
The stem part of the file name (before the .pdf)
should begin with "A1-report" and end with your repository name, e.g.
A1-report-baden-powell.pdf.
Document your work in a well-written, two to three page report, including plots, which presents your results, analyzes them, and offers insight. Your report should present a clear evaluation of the design of your code, including bottlenecks of the implementation. If you improved performance of your code in a sequence of steps, document the process. If you like, summarize the information in a list or a table in your report. If necessary, provide pseudo code to illustrate the concepts. Be sure to thoroughly explain the results presented in your plots, relating them to how you designed the code. Discuss the design decisions you made to improve performance, including any negative results.
An important part of your report is your analysis. That is, to provide insight that explains your results. For this reason, if you are running out of time, put more effort into the writeup and your analysis rather than trying yet another performance enhancement. It can take time to collect, tabulate and plot results, as well as offer a reasonable explanation. We prefer a deeper analysis involving a few program optimizations over a shallower analysis over a larger number of optimizations. Spend more time discussing the optimizations that made a difference and less on those that made less of a difference. Negative results are also especially valued if you carefully document them, with the underlying causes, or best guesses if the causes are unclear.
Do not include full code listings in your writeup as these will be in your turnin.
Take care in how you plot your data, plotting only what's necessary to get your points across. Choose log and linear plots carefully, to take advantage of the plotting space. You must also include any plotted data in tabular form. Tabular data may be included electronically (in your turnin) as a spreadsheet or other document called, e.g. Data.xlsx, Data.txt. Be sure to provide a caption for each plot or table that describes the experiment you conducted, e.g. "strong scaling."
Cite any written works or software as appropriate in the text of the report. Citations should include any software you used that was written by someone else, or that was written by you for purposes other than this class. In such cases you must talk with us (and any code co-authors) prior to get approval.
There are 10 possible points on the assignment and your grade will depend on 4 factors: performance attained by your code, correctness, well-displayed results and comments. You must not only put comments inside your code, but every time you commit to your repository. There should be a steady stream of comments that enable us to retrace your development steps.
Your performance score is divided into two parts. You'll get the bulk of those points for reaching 4 GFlops, but to get all points on performance, you must realize 5 GFlops. Again, these figures are averages taken over the full range of input sizes specified in the driver program, and not for individual inputs. While it is possible to approach the speed of the ATLAS (about 6.8 GFlops (about 70% of the processor's peak theoretical speed) it can take time to realize this performance, so beware!
We will grade your code (on bang) using our own Makefile. Our Makefile will compile your code using gcc and and then link it with the test driver which is similar to dgemm-blocked.c We will use the same compilation flags as in the provided starter code. To get full credit, design, style and comments (including gitlab commit comments) count.
Don't wait until the last minute to attempt a turnin for the first time. Try out the turnin process early on so you are sure that you you are familiar with the process, and that all the required additional files are present.
You will receive 0 points for this assignment if your code does not compile, including cases of non-compilation due to merge conflicts. If you developed your code on another machine you are responsible for properly testing on bang, else you may lose significant credit, possibly all 10 points depending on the circumstances. As mentioned previously, you must ensure that you resolve all of your merge conflicts and that your code compiles and runs correctly IMMEDIATELY BEFORE you push to GitLab.
For this assignment staff will attempt intervene manually to fix problems. However, the policy for such manual intervention is as follows. If any manual intervention is required by staff you will lose at least 2 points. Included are: incorrectly naming your GitLab repository, or misspelling the words FINAL SUBMISSION in the commit message. Lastly, the only files you should be pushing to GitLab are text files: source code and ASCII test files. Do not push large binaries such as the executables or media files, as doing so could lead to problems such as losing the ability to push to GitLab. Staff will not intervene under these circumstances and you you may be unable to complete your assignment by the deadline. If you commit binaries, you are doing so at your own risk.
Here are various sources of information that can help you optimize your code. The primary sources are seminal references. The Intel "SSE cheat sheet" will come in handy.
[Tue Oct 6 14:47:24 PDT 2015]