The presentation can be downloaded here.
How to combine the good
Good
A
All previously discussed optimizations works on procedural level:
To solve these problems the program has to be analyzed as a whole.
p, all local and killed (p).
Compiler needs to know which objects can be changed inside the function according to perform high-quality optimizations.
To obtain such information we need to analyze the entire program. This (interprocedural) infromation improves many classic intraprocedural optimizations.
In computer programming, a one-
In order to gather the information about a function properties the compiler needs to analyze every function and it’s interconnection with other functions because each them can contain any function calls, as well as itself call (recursion). It is necessary to analyze a edge (f, g) indicates that the procedure f calls procedure g.
A
One of the main of interprocedural analysis tasks is constructing the
(рис 8.1)
When the one-
In the case of the multi-
/Qipo[n] enables
/Qipo-c generate a multi-file object file (ipo_out.obj)
/Qipo-S generate a multi-file assembly file (ipo_out.
/Qipo-jobs<n> specify the number of jobs to be executed
There is a partial interprocedural analysis which works on single-file scope. In this case some partial
Qip[-] enable(DEFAULT)/disable single-file IP optimization within files
Interprocedural analysis collects MOD and REF sets for each routine. MOD/REF sets contain objects which can be modified or referenced during the routine execution.
These sets can be used for scalar optimizations.
external void unknown(int *a);
int main(){
int a,b,c;
a=5;
c=a;
unknown(a);
if(a==5)
printf("a==5\n");
b=a;
printf("%d %d %d\n",a,b,c);
return(1);
}
#include <stdio.h>
void unknown(int *a) {
printf"a=%d\n", *a);
}
Let’s consider a simple example. There are two files. Function main contains call of function "unknown" which is located in a other file.
We can use assembler files to define if check if(a==5) was deleted or wasn’t.
icl test.c unknown.c –S
There is this check in this case. Let’s inspect test.asm file .
call _unknown ;9.1 ... .B1.2: ; Preds .B1.8 mov edi, DWORD PTR [a.302.0.1] ;10.4 cmp edi, 5 ;10.7 jne .B1.4 ; Prob 0% ;10.7 icl –Ob0 test.c unknown.c -Qipo–S
With –Qipo check was eliminated. -Ob0 is needed to prevent inlining of unknown.
call _unknown. ;9.1 ... .B1.2: ; Preds .B1.7 push OFFSET FLAT: ??_C@_05A@a?$DN?$DN5?6?$AA@ ;11.3 call _printf ;11.3
It is used to determine if a storage location may be accessed in more than one way. Two pointers are said to be aliased if they point to the same location.
Alias analysis is important to find loop dependences.
#include <stdio.h>
int p1=1,p2=2;
int *a,*b;
void init(int **a, int **b) {
*a=p1;
*b=p1; // <= a and b poins to p1
}
int main() {
int i,ar[100];
init(a,b);
printf("*a= %d *b=%d\n",*a,*b);
for(i=0;i<100;i++) {
ar[i]=i*(*a)*(*a);
*b+=1; /* *a is changed through *b */
}
printf("ar[50]= %d p2=%d\n",ar[50],p2);
}
Dependence may appear if two pointers (a and b) reference the same
Interprocedural analysis is used:
"no_side_effect", "always_return", etc. used for "address was taken" than it cannot be updated through pointers, it simplifies many optimizations. Whole program analysis is required to handle the Simple example: If all calls of function f(x,y,z) have the same constant value for actual argument x, than x can be changed with this constant inside
Constant result propagation. If a procedure returns some constant value than this value can be propagated to
#include <stdio.h>
extern void known(int variant,int *var);
int main() {
int var;
int ttt;
var=2;
ttt=3;
known(var,ttt);
printf("ttt=%i\n",ttt);
void known(int var,int *ttt) {
if(var>0)
(*ttt)++;
else
(*ttt)--;
}
icc –Ob0 test.c known.c -fast -ipo-S ... known: # parameter 1: %edi # parameter 2: %rsi ..B2.1: # Preds ..B2.0 ..___tag_value_known.8: #1.30 addl $1, (%rsi) #3.3 ret #6.1 .align 16,0x90
#include <stdio.h>
int fcall(int x){
if(x>3)
printf("x>3");
else
printf("x<=3");
return x+1;
}
int main() {
int x,y;
x=2;
y=fcall(x);
x=1;
y=fcall(x);
}
It is easy to see that the "x" of function fcall can be equal in this program to values 2 or 1. If_condition inside fcall is resolved identically for this values. Let’s check if
icl test2.c –Ob0 –O3 –Qipo-S ??
Inlining or inline
Inlining reduces
Disadvantage of inlining is the application size increase.
Inlining
A programmer is able to recommend to inline function with inline attribute
For example,
inline int exforsys(int x1) {
return 5*x1;
}
REAL A(100)
INTEGER I
DO I = 1,100
A(I) = I
END DO
DO I = 1,100
CALL AADD(A,I,1)
END DO
PRINT *, A(100)
END
SUBROUTINE AADD(ARRAY,EL,AD)
REAL :: ARRAY(*)
INTEGER EL
REAL AD
ARRAY(EL)=ARRAY(EL)+AD
RETURN
END
Inlining allows to perform intraprocedural optimizations on the inlined
Inlining of
ifort -Ob0 test_vec.f90 -Qvec_report3 ...
..\test_vec.f90(10): (col. 2)
ifort test_vec.f90 -Qvec_report3 ...
C:\users\aanufrie\students\ipo\5\test_vec.f90(8):(col. 2)
Inlining directives
#pragma inline[recursive]#pragma forceinline[recursive]#pragma noinlineRecursive demands to inline all routines which are called by the marked call.
Directive
inline recommend to inline routinenoinline demand not to inline routineforceinline demand to inline routineFortran directives
cDEC$ ATTRIBUTES INLINE :: procedurecDEC$ ATTRIBUTES NOINLINE :: procedurecDEC$ ATTRIBUTES FORCEINLINE :: procedure/Ob<n> control inline n=0 disable inliningn=1 inline __inline, and perform C++ inliningn=2 inline any function, at the compiler's /Qinline-min-size:<n> set size limit for inlining small routines/Qinline-min-size- no size limit for inlining small routines/Qinline-max-size:<n> set size limit for inlining large routines/Qinline-max-size- no size limit for inlining large routines/Qinline-max-total-size:<n> maximum increase in size for inline function /Qinline-max-total-size- no size limit for inline function /Qinline-max-per-routine:<n> maximum number of inline instances in any function/Qinline-max-per-routine- no maximum number of inline instances in any function/Qinline-max-per-compile:<n> maximum number of inline instances in the current compilation/Qinline-max-per-compile- no maximum number of inline instances in the current compilation/Qinline-factor:<n> set inlining upper limits by n /Qinline-factor- do not set set inlining upper limits/Qinline-forceinline treat inline routines as forceinline/Qinline-dllimport allow(DEFAULT)/__declspec(dllimport) to be inlined/Qinline-calloc directs the compiler to inline calloc() calls as malloc()/memset()Cloning is a specializing a function to a specific class of call sites
Sometimes specific
Trivial case is a call of a procedure with a constant argument. For example, if there are several calls of some procedure f in form f(x,y,TRUE) and several calls f(x,y,FALSE) than sometimes it is profitable to create procedures f_TRUE(x,y) and f_FALSE(x,y) and replace initial calls with calls of new procedures.
Partial inlining is an
(рис 8.2)
The following types of
Structure splitting leaves hot (frequently used) fields in main structure and removes other fields to special frozen section. After this optimization data will need less memory and will fit
Compiler need to
#ifndef PERF
typedef struct {
double x;
char title[40];
double y;
char title2[22];
double z;
} VecR;
#else
typedef struct {
char title[40];
char title2[22];
} ColdFields;
typedef struct {
double x;
double y;
double z;
ColdFields *cold;
} VecR;
#endif
#include "struct.h"
int main() {
int i, k;
VecR *array = malloc(10000*sizeof(VecR));
#ifdef PERF
for(i=0;i<10000;i++)
array[i].cold=(ColdFields*)malloc(sizeof(ColdFields));
#endif
for (i=0;i<10000;i++){
array[i].x = 1.0; array[i].y = 2.0; array[i].z = 0.0; }
for(k=1;k<10000;k++) {
for (i=k;i<9999;i++){
array[i].x = array[i-1].y+1.0;
array[i].y = array[i+1].x+array[i+1].y;
array[i].z = (array[i-1].y - array[i-1].x)/array[i-1].y; } }
printf("%f \n",array[100].z);
#ifdef PERF
for(i=0;i<10000;i++)
free(array[i].cold);
#endif
free(array);
}
Result of
icc struct.c -fast -o a.out icc struct.c -fast -DPERF -o b.out time ./a.out real 0m0.808s time ./b.out real 0m0.566s
Data access through several pointers is one of the most common problem in C++ code. If a program data doesn’t fit in the
This problem can be caused also by wrong
(рис 8.3)
All_members+= employer->p->f->members;
C++ - object-oriented language with a high level of abstraction and ability to perform the class methods depending on the type of the object at run time. In this case pointers to different class methods are located in special table and call of virtual function is very expensive for the performance. Sometimes call through table of virtual method can be replaced with call of a specific method
A => B => C
All derived classes override virtual int foo ()
int process (class A * a) {
return (a-> foo ());
}
Devirtualization example
Class A isn’t used in this source, so it is possible to perform devirtualization.
#include <stdio.h>
class A {
virtual int foo() { return 1; };
friend int process(class A *a);
};
class B: public A {
virtual int foo() { return 2; };
friend int process(class A *a);
};
int process(class A *a) {
return(a->foo());
};
void main() {
B* pB = new B;
int result2 = process(pB);
}
icl test.cpp –S mov eax, DWORD PTR [ebx] mov ecx, ebx call DWORD PTR [eax] (call through table) icl test.cpp –Qipo_S –Ob0 -Qipo call ?process.@@YAHPAVA@@@Z
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.