OVH Cloud OVH Cloud

Seg fault lors d'une optimisation avec icc

23 réponses
Avatar
Student
Bonjour,

Lors de l'optimisation d'un code avec icc, j'ai eu un seg fault, apr=E8s
un petit analyse j'ai trouv=E9 que le programme essaye d'=E9crire sur un
tableau non alou=E9, l'allocation je le fait par des boucles puisque c
des tableaux de plusieur dimensions, (exemple pour un float ** :
allocation de float ** puis des float *), est ce que c possible que
lors de l'optilisation cette boucle soit traiter en bloques?, si c le
cas comment je peux eviter une telle erreur,
j'utilise : icc avec LDFLAFGS=3D-xW -tpp7 -O3

merci

10 réponses

1 2 3
Avatar
Dominique Vaufreydaz
Bonjour,

for(i=0;i<VAL; i++){
//traitements en boucles des tableaux
}


Si tu debordes du tableau ici, dans certains cas de compilation (genre option
de la taille des blocs d'allocation de memoire ou autre), ca passe parceque tu
ne debordes pas dans une zone non allouée. Avec d'autyres options de
compilation, ca fait planter ton programme.

Je reste d'accord avec les autres que les symptomes poussent dans ce sens...

Maintenant, tant qu'on aura pas ce code la... Un test pour voir ce qu'il en est,
il faudrait desactiver le traitement et juste faire tourner le programme en boucle
comme s'il faisait des choses mais virer ce for. Si ca plante plus, c'est que le traitement
est foireux.

Doms.

Avatar
Marc Boyer
Le 07-09-2006, Student a écrit :
[SNIP]
j'execute : op un problem de segfault, qui est aléatoire, après
chaque compilation il me sort un nouveau, mais qui touchent toute le
temps l'initialisation des tableaux par exemple, lorsque je vois avec
ddd, je trouve qu'il essaye d'initisaliser avec d'allouer!!!, j'elimine
pas la possiblité de faire des betises dans mon code, mais j'ai une
grande confiance en se que j'ai écris.


Moi, j'aurais une plus grande confiance en ce que tu as ecris
si tu avais essaye les outils dont je te parlais (plus le
MALLOC_CHECK_ si tu es sous Linux, cf man malloc), et que tu nous
disait qu'ils ne signalent aucun probleme.

s'étais ça, j'ai corriger des problèmes de conversion de type et
d'autres #remark que icc me présente, et voila ça marche
l'éxécution mais je suis trés loin des perf souhaités: je tourne à
60 MFLOPS.
désolé pour ce long message explicatif, mais je veux bien voir si
qlqn à une exlication sur ces perf, merci.


Ben pour commencer, il faudrait etre sur que c'est le meme code
qui tourne: fais-tu autant malloc/free dans le code Fortran
par exemple ?
Ensuite, ben, il faudrait faire tourner un profileur de
code pour voir quelles sont les fonctions les plus appellees.
Pour continuer (mais la, on arrive a mes limites de competences),
ce que j'ai retenu de mes cours de calcul numeriques, c'est
que la difference de perf viens souvent des defauts de cache.
Il faut donc arriver a voir, sur ta plateforme, si les taux
de defaut de cache sont les meme dans les deux codes.
Et si rien de ca ne donne de resultat, ben, faut aller
voir un numericien.
Optimiser du code numerique, c'est un boulot en soit.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)

Avatar
Alain Gaillard

ne pariez sur rien, le code publier est à titre indicatif,


Alors je vais te dire. Ton code publié fuit.
S'il n'est qu'indicatif, il n'indique rien d'autre qu'il fuit et qu'il
est mal écrit.
Maintenant si tu demandes de l'aide sans donner d'infos fiables ou
complètes et que d'un autre côté tu es sûr de ton code, je vois mal ce
qu'on pourrait faire pour t'aider et il vaut mieux que tu cherches seul.

Pour la dernière fois, ce que tu as décrit comme problème est
*typiquement* le symptôme d'un bug (ou plusieurs) dans ton code, et non
dans icc.

Je te suggère de suivre le conseil de Marc et tu verras que c'est ton
code qui est en cause et pas icc.


--
Alain

Avatar
Marc Boyer
Le 11-09-2006, Student a écrit :
Merci à vous tous,
alors j'ai suis les remarques que icc m'affiche, j'ai placer la
variable MALLOC_CHECK_ à 1, tout ce passe bien pas de problème, pas
de seg fault non plus


Le fait que le passae de MALLOC_CHECK_ à 1 supprime le seg fault
m'incite encore plus à penser que le code est faux, mais fonctionne
par [mal]chance. C'est du code qui "tombe en marche".
valgrind est un outil plus tatillon que la simple mise à 1 du
MALLOC_CHECK_.

le problème qui me reste à résoudre est celui des
performances sur la version C, et si vous avez des remarques sur les
options utilisés dans ce makefile n'hésitez pas, merci.


Je t'ai déjà répondu: il faudrait déjà être *sur* que c'est le
même algo (cf mes remarques sur les accès mémoires et le cache).

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)

Avatar
Student
Merci à vous tous,
alors j'ai suis les remarques que icc m'affiche, j'ai placer la
variable MALLOC_CHECK_ à 1, tout ce passe bien pas de problème, pas
de seg fault non plus, je compile avec le make file suivant :

#voici l'entete du makefile:
malloc: using debugging hooks
EXEC=../bin/onde2
OBJDIR=objects/
...
CC=icc
all:$(EXEC)

CFLAGS = -I../include -Wall -Wuninitialized -msse2
LDFLAGS = -xW -tpp7 -fast -fprofile-arcs -ftest-coverage -g -O3 -lm
-I../include
#C_RELEASE_FLAG = -O3 -funroll-all-loops -fexpensive-optimizations -g
-ffast-math -finline-functions -finline-limit000 -frerun-loop-opt
-I../include/

../bin/onde2: $(OBJ)
$(CC) $(LDFLAGS) -o $(EXEC) $(OBJ)
echo "$(EXEC)"

le bout du code que j'avais publié était juste pour expliquer se que
je fait, sinon je suis totalement open, je l'ai fait pour caché mon
code pouri, le problème qui me reste à résoudre est celui des
performances sur la version C, et si vous avez des remarques sur les
options utilisés dans ce makefile n'hésitez pas, merci.

merci à Marc, Alain, Doms, et Michel.

Hicham



ne pariez sur rien, le code publier est à titre indicatif,


Alors je vais te dire. Ton code publié fuit.
S'il n'est qu'indicatif, il n'indique rien d'autre qu'il fuit et qu'il
est mal écrit.
Maintenant si tu demandes de l'aide sans donner d'infos fiables ou
complètes et que d'un autre côté tu es sûr de ton code, je vois m al ce
qu'on pourrait faire pour t'aider et il vaut mieux que tu cherches seul.

Pour la dernière fois, ce que tu as décrit comme problème est
*typiquement* le symptôme d'un bug (ou plusieurs) dans ton code, et non
dans icc.

Je te suggère de suivre le conseil de Marc et tu verras que c'est ton
code qui est en cause et pas icc.


--
Alain



Avatar
Student
petite rectif,
je fait, sinon je suis totalement open, je l'ai fait pour caché mon
Je veux dire : je l'ai pas fait pour cacher mon code pouri :)

code pouri, le problème qui me reste à résoudre est celui des


Avatar
Student
t'a tout à fait raison, car j'ai tombé sur un autre piège, en faite
je dispose de deux version de icc, la 9.0 et la 9.1, sur la 9.1 il
marche sans seg fault et sur la 9.0 il marche pas!!!
On fait ce qui m'etonne c'est que lorsque de compile avec -g il a pas
de prob sinon il s'arrete sur cette erreur :

onde2: src/tools.c:31: initArrayf2D: Assertion `(c != 0L)' failed.
Abort

alors voici le code qui mene à cela:
c = allocArrayf2D(x,y);
initArrayf2D(c,x,y ,2.);

float ** allocArrayf2D(int x, int y){
float **a;
int i,j;
if( (a = (float **)malloc(sizeof(float*)*x)) == NULL){
fprintf(stderr,"Error:allocation Failed n");
return NULL;
}
for( i = 0; i<x; i++){
if( (a[i] = (float*)malloc(sizeof(float)*y)) ==NULL){
fprintf(stderr,"Error:allocation Failedn");
for( j=i-1; j>-1; j--){
free(a[j]);
}
free(a);
return NULL;
}

int
initArrayf2D(float** c,int xi, int xj,float value){
assert((c != NULL)); //------->> il s'arrete ici
int i,j;
for(i=0; i<xi; i++)
for(j=0; j<xj; j++){
c[i][j]=value;
}
return a;
}



Merci à vous tous,
alors j'ai suis les remarques que icc m'affiche, j'ai placer la
variable MALLOC_CHECK_ à 1, tout ce passe bien pas de problème, pas
de seg fault non plus


Le fait que le passae de MALLOC_CHECK_ à 1 supprime le seg fault
m'incite encore plus à penser que le code est faux, mais fonctionne
par [mal]chance. C'est du code qui "tombe en marche".
valgrind est un outil plus tatillon que la simple mise à 1 du
MALLOC_CHECK_.

le problème qui me reste à résoudre est celui des
performances sur la version C, et si vous avez des remarques sur les
options utilisés dans ce makefile n'hésitez pas, merci.


Je t'ai déjà répondu: il faudrait déjà être *sur* que c'es t le
même algo (cf mes remarques sur les accès mémoires et le cache).

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)



Avatar
Marc Boyer
Le 11-09-2006, Student a écrit :
t'a tout à fait raison, car j'ai tombé sur un autre piège, en faite
je dispose de deux version de icc, la 9.0 et la 9.1, sur la 9.1 il
marche sans seg fault et sur la 9.0 il marche pas!!!
On fait ce qui m'etonne c'est que lorsque de compile avec -g il a pas
de prob sinon il s'arrete sur cette erreur :

onde2: src/tools.c:31: initArrayf2D: Assertion `(c != 0L)' failed.
Abort


Comme déjà dit au moins 3 fois, c'est caractéristique d'un code
faux mais qui marche par [mal]chance.

alors voici le code qui mene à cela:
c = allocArrayf2D(x,y);
initArrayf2D(c,x,y ,2.);

float ** allocArrayf2D(int x, int y){
float **a;
int i,j;
if( (a = (float **)malloc(sizeof(float*)*x)) == NULL){
fprintf(stderr,"Error:allocation Failed n");
return NULL;
}
for( i = 0; i<x; i++){
if( (a[i] = (float*)malloc(sizeof(float)*y)) ==NULL){
fprintf(stderr,"Error:allocation Failedn");
for( j=i-1; j>-1; j--){
free(a[j]);
}
free(a);
return NULL;
}


Il manque pas un
--------------------------
}
return a;
}
--------------------------
au code que tu postes ?


int
initArrayf2D(float** c,int xi, int xj,float value){
assert((c != NULL)); //------->> il s'arrete ici
int i,j;
for(i=0; i<xi; i++)
for(j=0; j<xj; j++){
c[i][j]=value;
}
return a;


C'est quoi 'a' ?

}


Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)

Avatar
Student
erreur de frappe,
float ** allocArrayf2D(int x, int y){
float **a;
int i,j;
if( (a = (float **)malloc(sizeof(float*)*x)) == NULL){
fprintf(stderr,"Error:allocation Failed n");
return NULL;
}
for( i = 0; i<x; i++){
if( (a[i] = (float*)malloc(sizeof(float)*y)) ==NULL){
fprintf(stderr,"Error:allocation Failedn");
for( j=i-1; j>-1; j--){
free(a[j]);
}
free(a);
return NULL;
}
return a; // c'est ici le 'return a;'
}

et le initArrayf2D c'est ça :

int
initArrayf2D(float** c,int xi, int xj,float value){
assert((c != NULL));

int i,j;

for(i=0; i<xi; i++)
for(j=0; j<xj; j++){
c[i][j]=value;
// printf(" c[%d][%d]=> %f n",i,j,c[i][j]);
}
return EXIT_SUCCESS;
}




t'a tout à fait raison, car j'ai tombé sur un autre piège, en fa ite
je dispose de deux version de icc, la 9.0 et la 9.1, sur la 9.1 il
marche sans seg fault et sur la 9.0 il marche pas!!!
On fait ce qui m'etonne c'est que lorsque de compile avec -g il a pas
de prob sinon il s'arrete sur cette erreur :

onde2: src/tools.c:31: initArrayf2D: Assertion `(c != 0L)' failed.
Abort


Comme déjà dit au moins 3 fois, c'est caractéristique d'un code
faux mais qui marche par [mal]chance.

alors voici le code qui mene à cela:
c = allocArrayf2D(x,y);
initArrayf2D(c,x,y ,2.);

float ** allocArrayf2D(int x, int y){
float **a;
int i,j;
if( (a = (float **)malloc(sizeof(float*)*x)) == NULL){
fprintf(stderr,"Error:allocation Failed n");
return NULL;
}
for( i = 0; i<x; i++){
if( (a[i] = (float*)malloc(sizeof(float)*y)) ==NULL){
fprintf(stderr,"Error:allocation Failedn");
for( j=i-1; j>-1; j--){
free(a[j]);
}
free(a);
return NULL;
}


Il manque pas un
--------------------------
}
return a;
}
--------------------------
au code que tu postes ?


int
initArrayf2D(float** c,int xi, int xj,float value){
assert((c != NULL)); //------->> il s'arrete ici
int i,j;
for(i=0; i<xi; i++)
for(j=0; j<xj; j++){
c[i][j]=value;
}
return a;


C'est quoi 'a' ?

}


Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)



Avatar
Marc Boyer
Le 11-09-2006, Student a écrit :
erreur de frappe,


Oui, mais ça fatigue les gens qui prennent du temps
pour t'aider.

float ** allocArrayf2D(int x, int y){
float **a;
int i,j;
if( (a = (float **)malloc(sizeof(float*)*x)) == NULL){
fprintf(stderr,"Error:allocation Failed n");
return NULL;
}
for( i = 0; i<x; i++){
if( (a[i] = (float*)malloc(sizeof(float)*y)) ==NULL){
fprintf(stderr,"Error:allocation Failedn");
for( j=i-1; j>-1; j--){
free(a[j]);
}
free(a);
return NULL;
}
return a; // c'est ici le 'return a;'
}

et le initArrayf2D c'est ça :

int
initArrayf2D(float** c,int xi, int xj,float value){
assert((c != NULL));

int i,j;

for(i=0; i<xi; i++)
for(j=0; j<xj; j++){
c[i][j]=value;
// printf(" c[%d][%d]=> %f n",i,j,c[i][j]);
}
return EXIT_SUCCESS;
}


Je ne vois rien de grave dans ce code.

onde2: src/tools.c:31: initArrayf2D: Assertion `(c != 0L)' failed.
Abort


Comme déjà dit au moins 3 fois, c'est caractéristique d'un code
faux mais qui marche par [mal]chance.

alors voici le code qui mene à cela:
c = allocArrayf2D(x,y);
initArrayf2D(c,x,y ,2.);




Le 'Assertion `(c != 0L)' failed' signifie que c est NULL,
ce qui peut simplement venir du fait que malloc a retourné
NULL, ce qui n'est pas en soit un bug.


Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. Paul Éluard)



1 2 3