Averaging Filter Basic SHARC assembly and adding automated tests Example of project development on SHARC using C++ and assembly Planned for Tutorial Thursday 2nd October 1 Concept “Single Point Copy” Audio Filter • Co-operative operating system used – SHARC uTTCOS guarantees that only one task will run at a time – Means, tasks ARE NOT swapped out but run-in-turn with the exception of ONE pre-emptive task (which interrupts other tasks) • You can automatically generate files for a uTTCOS project in ENCM515/Assign1 directory using uTTCOS_Helper plug-in – Hidden hardware capture of audio signal causes an interrupt that places audio values in a known location • You must add a pre-emptive task to process the audio signal to the uTTCOS to-do list of tasks – Pre-emptive tasks must have fast ‘in-and-out fast’ characteristics – absolute minimum time spend in pre-emptive task. Must be guaranteed to finish with 50% of 1 system TIC 2 Add Pre-emptive task to uTTCOS to-do list. Use to test audio equipment in lab. Use of include path operation means only 1 header files across 3 projects • • The code will not run in the lab because of a logical defect) What’s the defect? Project should compile with Copy_Left( ) 3 stub RECAP --Learn optimization via basic DSP algorithm “Average last N points” (trivial LP filter) Requirements – Output signal of filter y[n] is average of last N input values x[n-j], 0 <= j < N – y[n] = ( (x[n] + x[n-1] ……..x[n – (N-1)]) ) / N Need to store (and update) last N audio values captured – Need to store in first-in first-out (FIFO) buffer Problem -- audio start up transient – How do you handle the first “N” values? • Assume that x[-1], x[-2] …. X[n – (N-1)] = 0. • Basically means you pre-fill the FIFO buffer with zeros • y[0] = ( x[0] + 0 + 0 + 0 ) / N; 4 RECAP -- Code Design • Discard oldest value in FIFO (oldest was first in, so first out • This provides room to add new value to FIFO buffer • Output calculated by averaging all values in FIFO • Note N will be set as small number (e.g. N = 16) during some parts of test, and set large when timing done. – Don’t hand in labs handed in with poor timing test (D) • Use no magic numbers use in code – No loops involving for (j = 0; j < 1024; j++) – Use (j = 0; j < N; j++) where N is declared in Assign1.h so a single N is used across project including C, C++ and ASM 5 Develop a personal software process to minimize mistakes and wasted time • Do a code review for syntax errors – Make a list of errors so that you can identify YOUR most common mistakes AND STOP making them – One less repeated error per laboratory minimum • The number of syntax errors the compiler finds after your code review is related to the number of logical (unfound) defects in your code. • The number of syntax errors the compiler finds after your code review is related to the amount of time you will waste debugging your code looking for those hidden defects you did not find. • Watts Humphreys PSP – If spend 30 minutes coding then spend 25% of 30 minutes on review 6 RECAP -- Understanding C properly is a key to real-time programming • What does this code mean? -- Keyword ‘static’ • It means – When loading the program and data into the processor’s data and program memory using the embedded system BOOT sequence, make permanent private space ‘in general memory’ for an array FIFO[ ]. – As part of the embedded system BOOT sequence set all the values to zero before starting the program • NOTE: This setting to zeroes is NOT a run-time operation • NOTE: If restart the program (rather than reloading it), then ZEROS are not stored in FIFO[ ] – unknown E.B. values are stored there. 7 RECAP Try out averaging code • Build Assign1Library project , then CLEAN and build Assign1 project to force it to use new library (Eclipse bug) • Averaging removes high frequencies. • Old vinyl records (1920) lacked high frequency components • Assignment 1 : – What value of N to make 2011 music sound like 1920? – What does this sort of averaging do, and why? 8 Build Library – Clean and Build project- Expect a linker error to be reported as no new code is present • Check that error message is what you expect Missing function is NAME-MANGLED meaning than Linker is looking for C++ code and not assembly code. Typically means that “header file is wrong” ASK ME WHAT IS WRONG WITH HEADER FILE AND THEN NOTE IN IN YOUR NOTES 9 Understanding the code we use • This processor has two kinds of memory – dm – data memory – pm – program memory • HARVARD architecture of processor – Ability to access data memory and program memory at the same time. – Major speed improvement over von Neumann architecture 10 Accesses can be made directly to a specific memory address • Just because you can access memory this way, does not mean that this is the fastest code ?? #define _LeftChannel_In1 0x40???? // Used “extern” on last slide so define issue is solved automatically by the linker 11 Assembler message with adjustment Output volume is zero – WHY??? 12 Output volume is zero after we do the multiply • Need to switch to a testing environment to work out why. – Actually, we can make a guess. • We are doing ‘integer mathematics’ (a.k.a. Blackfin) • Blackfin and MIPS – 300 cycles for FADD via special floating point subroutines • SHARC is ‘floating point ‘ processor – 1 cycle for FADD via special floating point instructions F2 = F2 * F5 (float multiplication) R2 = R2 * R5 (two types of integer) • In future, we will set up tests first so that we know what the answer will be from complex algorithms. 13 Avoid this refactoring defect Note CCES warns you (some what) But unless you read the warning then it does not help Mistake you made Assembler trying to warn you that you are using an “integer” op rather than a floating point operation 14 Assembler is ‘lying’ (Disassembly window) Only 1 in 5 is ‘real float’ instruction NO NEED TO USE SILICON FOR UNNECESARY FLOAT INSTRUCTIONS WHEN EXISTING INTEGER WORK “PERFECTLY WELL” • Memory stores are bit patterns – not floats or integers • Constants are bit patterns -- not integers or floats 15 XP-Inspired Life cycle for real-time DSP (see Smith et al articles on 515 web-site) • • • • Design – wish-list of ‘stories’ to implement Write Tests to show how code should work Write C++ code to satisfy tests (Get to work) Generate resource chart based on processor architecture to calculate best ‘theoretical’ speed – If ‘theoretical speed’ meets your ‘real-time requirements’ you, then worth while trying to optimize!. – If ‘theoretical speed’ does not work for you then ‘find a different algorithm’, optimization is not going to help. • Use already written tests to prove that (highly optimized) assembly code WORKS as well as being fast • NOTE: Theory calculation etc. is done WITHOUT writing any assembly code. Timing calculation is all about “thinking” about what is needed and about actually not doing it. Assembly coding comes when it is needed and not before 16 Lets try the approach with CopySingle( ) OFF-LINE testing – without uTTCOS, with faked audio signals • Assign1_Tests – convert to E-Unit using Open-CCES-ame Plug-in • First test will be for ‘CopySingleCPP’ • Change include path for .h to include Assign1_Library and add (debug version) Assign1_Library.dlb 17 Inside ‘Assign1_Test’ project There are .h and .dlb links into Library Make LINKS to Assign1 Library.dlb and .h header files in directory and NOT copies of files and libraries Done by adding library path and include path information 18 Modify tests to validate C++ and assembly copy routines • Confusing – Cntrl-SPACE completion macro knew about LeftCPP( ) etc – but look at all error warnings 19 Did a project clean and then build Do code review to find final error This was a refactoring error when I changed file names Change CONTROL and NOTIFY macros to include CPP (See next slide) 20 Big errors on Build and Link • WE ARE TESTING OFF_LINE -- We are no longer running with a real audio interface (All variables defined in uTTCOS_Library used in Assign1 project) • Actually good – Since we don’t know the actual audio values coming in when running in real-time, then we can’t test to see if we are processing them correctly • Solution – Build a mock audio device and add the code to the project. 21 Here is the Mock Audio Device Ask me how do I fix the error? • Is my coding mistake an “error” or a “defect”? • Did I do a code review before compiling? 22 Run the tests -- Missing Open-CCES-ame feature Click and go to Error. For now Right click on blue bar to show line numbers CLICK ON ERROR TO GO TO FAILING TEST – NOT YET POSSIBLE IN CCES. (If somebody is 23 good at Java – I will tell them what is needed and we can discuss a price) CLICK ON ERROR TO GO TO FAILING TEST – NOT YET POSSIBLE IN CCES • If somebody is good at Java – I will tell them what is needed and we can discuss a price. – – – – We could double the money by jointly writing a CC article on this. Published articles look good on CVs and scholarship application They are not “articles” but “technical transfer papers” on your CV Also possible to do during 4th year projects • We have example code running in C++ and C# for an earlier IDDE • In principle I could do this (if I had the time) – Find and capture the console window – Parse through console window and rewrite error messages in colour • This is out of my “Java” comfort zone – Make the error clickable so that we can make the editor jump to that location 24 Straight forward to add more tests to see if there is a pattern in the defect result Why is there a code defect and not a code error? Depending on your definition s -- Why is there a design defect and not a code error? 25 Is there a pattern in the error messages? If exists, then hints at defect to solve • Output value is wrong, but the wrongness scales with the input value size (NGTTY- HLTTMTWO) 26 Use Open-CESS-ame to add new test group for Averaging code – 3 styles of tests 27 Time test – measure in us Must be less than 20 us per point (1 audio channel) Timing MUST be done with long fil What is filter length here NEW REQUIREMENT Add the size of the averaging filter as part of the printf statement Un-automated testing, But we need to collect details And don`t have to do much analysis in Lab Only doing 5 labs – not yet worth automating? 28 Interesting CCES IDDE code ran at different speed than VDSP IDDE code CCES has different C++ device buffer characteristics apparently for printf( ) 29 Let`s try optimizing the C++ code (Switching between debug and release development) • Right click Assign1Library.cpp and make a copy as Assign1LibraryOptimized.cpp • Change function names e.g. AverageSingleAudioValue_LeftCPP to AverageSingleAudioValue_LeftCPPOptimized – delete other functions in file • Add new function to include file • Right click on Assign1LibraryOptimized.cpp and select properties • Under C/C++ Build | Settings select General and then Enable Optimization Note – we are just optimizing the C++ code in this file and not in the whole library 30 Add new test for optimized code Modify EUNIT main to show only failures Don’t understand why there is an editor indicated error. Tried CLEAN Big difference between optimized and unoptimized C++ Question is the code still working now its optimized (Actually never tested before) 31 New test – used to compare to ‘theoretical’ Analysis of cycles used in code Remember – we are also • timing the time around the loop • and the time to jump in and out of 32 routines Testing the code’s correctness should have been done before optimization • Warning – if FIFO_SIZE Note – This test “assumes” is small that input signals is staying when constants testing – then will Need a better test pass timing tests but be useless in real life 33