重点章节 | Page | 导读 |
2. Optimizing C/C++ Code | ||
2.1 Writing C/C++ Code | 2 | |
2.2 Compiling C/C++ Code | ||
2.2.1 Compiler options | 3 | 介绍了重要的编译选项 -g, -o3, -k -mw, -mi, -mh, -pm |
2.2.2 Memory Dependencies | 4 | 介绍了什么是memory dependency以及使用restrict |
2.3 Profiling Your Code | 2 | 这部分有些过时了,可以不看。TI local FAE开发了一个很好的profiling工具,采用function hook的办法可以profiling函数的执行次数和消耗的cycle数。需要6.1版本以上的编译器才能支持。 |
2.4 Refining C/C++ Code | ||
2.4.1 Using Intrinsics | 14 | 介绍使用intrinsic 优化代码,有intrinsic的列表。不过仅限于C64+,其实除了load/store的操作之外,intrinsic基本和DSP指令是一一对应的,所以可以参考TMS320C66x DSP CPU and Instruction Set Reference Guide sprugh7.pdf,较全的intrinsic可以在..compilerc6000includec6x.h中找到, |
2.4.2 Wide Memory Access for Smaller Data Widths | 18 | 举例说明怎样最大限度利用DSP D单元的存取位宽 (64bits)。 包括使用_nassert()和MUST_ITERATE pragma等 |
2.4.3 Software Pipelining | 12 | 比较重要的几个章节如下,介绍了几个关键的预编译指令。内容顾名思义 2.4.3.1 Trip Count Issues 解释了什么是softare pipeline的minimum safe trip count。 2.4.3.2 Eliminating Redundant Loops, 在循环的最少循环次数未知时,编译器会生冗余的循环。介绍了什么是冗余循环以及怎样消除它。 2.4.3.3 Communicating Trip-Count Information to the Compiler 2.4.3.4 Loop Unrolling 2.4.3.5 Speculative Execution (?mh option) 2.4.3.6 What Disqualifies a Loop from Being Software-Pipelined |
3 Compiler Optimization Tutorial | ||
3.1 Introduction: Simple C Tuning | ||
3.2 Lesson 1: Loop Carry Path From Memory Pointers | 8 | demo了什么是loop carry dependency,以及怎样消除dependency。这个例子在消除dependency后可以使循环cycle数减少到原来的1/5。loop carry dependency是导致代码抵消的最普遍的原因。在循环中如果有对两个以上数组读写,基本都会存在loop carry dependency的问题 |
3.3 Lesson 2: Balancing Resources With Dual-Data Paths | 5 | 由于C64,C64+,c66的core都是分成A,B两套datapayh和register file的,所以balance resource 也很重要。这一节用例子demo了怎样加#pragma MUST_ITERATE使循环效率提高了1.5倍 |
3.4 Lesson 3: Packed Data Optimization of Memory Bandwidth | 5 | 由于DSP的D单元的最大存取宽度是64bit,但是通常的操作数最大就是32bit。为了充分利用D单元,可以用预编译指令 (_nassert(((int)(x) & 0x3) == 0))告诉编译器数组的对齐特性。编译器在优化时就会尽量使用一次load/store 64bit的宽存取指令。如果编译器的优化效果不好还可以手工使用intrinsic _amem8()或 _mem8()一次load多个操作数。这一节就demo了这样一个例子。优化后循环效率提高了1.5倍。 |
3.5 Lesson 4: Program Level Optimization | 2 | 一般编译器是以文件为单位做优化的。启用program level优化后,编译器会对整个工程的source code combine到一起生成一个中间文件。Program level优化主要从以下几个方面改进优化效果。 a) If a particular argument in a function always has the same value, the compiler replaces the argument with the value and passes the value instead of the argument. b) If a return value of a function is never used, the compiler deletes the return code in the function. c) If a function is not called, directly or indirectly, the compiler removes the function. d) Also, using the −pm option can lead to better schedules for your loops. If the number of iterations of a loop is determined by a value passed into the function, and the compiler can determine what that value is from the caller, then the compiler will have more information about the minimum trip count of the loop leading to a better resulting schedule. |
3.6 Lesson 5: Writing Linear Assembly | 可以略过,这种优化方法目前基本不使用 | |
4. Feedback[1]Solutions | 22 | 这一章非常重要,介绍了怎样理解编译器的反馈信息。编译器在优化时是着力于代码中的循环的,因为循环最消耗cycle。 编译器能输出asm文件,asm文件中有每个循环优化后的pipeline信息。读懂这些信息能指导我们消除瓶颈,进一步提升循环的效率。 优化其实是个反复调整的过程: 代码优化->编译->读编译反馈的pipeline信息->下一轮代码优化->... 有经验的工程师看了asm文件中有每个循环优化后的pipeline信息后就可以明确 哪些循环已经达到优化极限,那些还有提升空间。这样可以做到有的放矢。 |
5. Optimizing Assembly Code via Linear Assembly | 可以略过,这种优化方法目前基本不使用 |
章节 | pages | 导读 |
2 Overview of the TMS320C6600 | ||
2.1 Key Additions | ||
2.2 C66x Floating-Point Overview | ||
2.3 128-Bit Data Type | ||
3 C66x Floating-Point and Vector/Matrix Operations and Optimizations | ||
3.1 Floating-Point Arithmetic | 15 | 介绍了用浮点的复乘和求倒指令优化循环的例子。优化后的代码cycle数减小,计算精度提升 |
3.2 Complex Matrix Operation and Vector Operations using Advanced C66x Fixed-Point Instructions. | 4 | 介绍了用cmatmpyr1结合dsadd2指令计算4×4复矩阵乘与4×4复矩帧的代码优化。优化的结果是pipeline起来计算这样一组乘法需要12个cycle |
3.3 Matrix Inversion Considerations . | 1 | 简单描述了C66x用于矩阵求逆运算的优势,没有例子 |
4 Additional Tuning Techniques for C66x Software-Pipelined Loops . | ||
4.1 Reducing Register Pressure in the TMS320C66x . | 14 | 结合MMSE equalizer的例子介绍了怎样解决寄存器压力过大的问题。C66的寄存器个数和C64+相同,在使用了占用大量寄存器的指令(例如矩阵乘和更宽的SIMD)以后很容易出现寄存器压力过大的问题。所谓寄存器压力过大就是由于循环中有大量临时变量。编译器没有足够的寄存器分配给这些临时变量,编译器不得不减少展开的次数或者把部分局部变量存在stack中,这都会导致循环效率的降低。减少寄存器压力过大的主要方法是掺杂使用4way SIMD指令和2 way SIMD指令。不过这又会影响A B datapath的balance,所以要找到最好的平衡点需要不断尝试。这里还介绍了使用DMV指令消除寄存器压力过大的方法。不过这种用法太讲究。需要对pipeline做细致的分析。只有精益求精抠一两个cycle的时候才会用到。 |
4.2 C66x Limitation on Common Sub Expressions (CSE) . | 2 | 在C66上如果指令的计算结果是128bit数,而且这个结果会被多出使用,那么一定要定义一个128bit临时变量,先把计算结果赋值给这个临时变量,再在其他多处使用这个临时变量。 这是由于 Limitation on Common Sub Expressions 需要check一下这在7.4的编译器上是不是已经被fix了。 |
4.3 Live-Too-Long Problem in C6000 C Code. | 2 | 解释什么是临时变量live-too-long的问题。因为编译器生成的pipeline信息中有时会报register live too long ,这里形象的解释了这个问题。 |
章节 | pages | 导读 |
5.1 Restrict Qualifying Pointers Embedded in Structures | 6 | 在结构体中restrict-qualification是不能传递的。假设有结构体 typedef struct[ short * data1; short * data2; ]s; 即使我们声明s结构体指针为restrict-qualified,但是结构体中的指针s->data1, s->data2p仍然是non-qualified。 解决的办法是代码中定义局部的restrict-qualified指针。把结构体内部的指针赋值给这些局部指针,用局部指针来访问数组 例如: 下面定义了局部指针ptr1和ptr2。把结构体内部指针s->data1和s->data2赋值给它们。后续的运算使用指针ptr1和ptr2来访问数据。 short * restrict ptr1; short * restrict ptr2; ptr1 = s->data1; ptr2 = s->data2; |
| 5.2 Optimizing “If” Statements | 在循环中如果有复杂的if/else分支会导致Disqualified loop,编译器不能产生software pipeline。这一张通过7个小节case by case的介绍了怎样拆解简化循环中的条件分支: 5.2.1 If-Conversion 5.2.2 “If” Statement Reduction When No “Else” Block Exists 5.2.3 “If” Statement Elimination 5.2.4 “If” Statement Elimination By Use of Intrinsics 5.2.5 “If” Statement Reduction Via Common Code Consolidation 5.2.6 Eliminating Nested “If” Statements [Comments]1~6小节主要是编程技巧 5.2.7 Optimizing Conditional Expressions [comments]多个条件相与相或要使用&和|,而不要使用&&和||,&&和||其实等效于嵌套循环。 | |
| 5.3 Handling Function Calls | 介绍了编译器自动inline的原则以及编译选项-oi的参数对自动inline程度的影响 | |
| 5.4 Improving Performance of Large Control Code Loops | 包括两个小节: 5.4.1 Using Scalar Expansion to Split Loops 太大太复杂的循环会导致" Disqualified loop: Too many instructions ",也就是由于循环中的运算操作太多,导致编译器放弃做software pipeline优化。解决这个问题的办法是把大循环劈开到成多个小循环。 5.4.2 Optimizing Sparse Loops 所谓稀疏循环是指循环中有条件判断,当条件成立才执行大量运算,而条件成立的概率不大。优化这种循环的办法是把原来的大循环拆成两个小循环,第一个循环先计算并存储条件成立的index,第二个循环在按照这个index列表对满足条件的数据机型处理。 |
举报
举报
举报
更多回帖