Van egy kb 25 eve irt kodreszlet, ami akkoriban (2.9x gcc-vel) mukodott jol, most pedig gcc 11.x-el mar nem mindig (nehez reprodukalni, nem mindig szar csak ritkan). Ha belerakok egy printf-et akkor viszont jol mukodik, ezert gondolom h valami optimalizalasi bug lehet. Probaltam volatile-t is irni a deklaraciohoz, bar elvileg nem kene, de az sem segitett rajta. Ha a hibakezelest (if..return 0) is kivettem, akkor se lett jobb.
Mi a hiba? :)
INLINE static int afs_fread_dword(dword *ptr,int s1,int s2,afs_FILE *f){ int s=s1*s2/4; while(s>0){ volatile dword c; if(afs_fread(&c,sizeof(c),1,f)!=1) return 0; printf(" s=%d c=0x%08X ptr=%p\n",s,c,ptr); #ifdef REVERSE_BYTEORDER c= ((c>>24)&0xFF) | (((c>>16)&0xFF)<<8) | (((c>>8)&0xFF)<<16) | ((c&0xFF)<<24); #endif *ptr=c; ++ptr; --s; } return s2; }
kiirattam a parameteretekt, az s2 mindig 1, az s1 pedig 4/8/12/16/32 tehat nem lehet az a baja, hogy nem oszthato 4-el (dword merete)
ha az egesz fuggveny belsejet kicserelem erre az 1 sorra, akkor is jol mukodik: return afs_fread(ptr,s1,s2,f);
- 748 megtekintés
Hozzászólások
Mit csinal? Mit nem kellene csinalnia?
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
ugyanazt mint a posix/libc fread(), csak extrakent opcionalisan kezeli a byteorder swap-et. szoval semmi extrat.
ha csak siman meghivja az fread-et akkor mukodik, de ha dwordonkent kulon hivogatja akkor meg nem jo neha. persze a printf megjavitja, szoval nem az fread reszevel van a baja, hanem a ciklust optimalizalja neha szarul a gcc...
- A hozzászóláshoz be kell jelentkezni
A kodot elolvastam, es ertem. Mit jelent az, hogy "nem mukodik"?
Amugy milyen architektura, es a REVERSE_BYTEORDER be van kapcsolva, amikor nem megy? gcc -S-sel esetleg meg lehet nezni mire fordul. Ha tudod a bithosszt, uint32_t jobb dword helyett, bar itt nem azon mulik. Plusz te nyilvan tudod a muveleti sorrendet, de ezeket szeretem zarojelezni, mert tobb nyelvet hasznalok parhuzamosan, es fene tudja hol mi undefined behaviour: (s1*s2)/4 (ugye ha s2 mondjuk 3, es elobb osztja, s 0 lesz, es kilep)
Amugy asszem ha a forditott bytesorrend inaktiv, siman visszaternek az fread-del. A bitcserelgetesre is van muvelet, pl. itt alapvetoen nem jo ezeket ciklussal ujrairni, nem is lesz gyors, mas atgondolta helyettem, optimalizalta, es tesztelte.
Multithread kornyezet amugy? Amiatt is lehet ritkan elojovo hiba.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
Multithread kornyezet amugy? Amiatt is lehet ritkan elojovo hiba.
Arra gondolsz, hogy valami nem atomikus?
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Arra, hogy ugyanide masik szalon is beter, mas thread is elkezd ebbol olvasgatni, es hulyeseg lesz az eredmeny. A printf megkavarja az idoziteseket, es ugy a szerencses veletlennek koszonhetoen kevesbe akad ossze.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
> Mit jelent az, hogy "nem mukodik"?
ez egy .3ds file loaderben van, 3d modelleket tolt be es jelenit meg opengl-el, es neha el van fordulva 90 fokkal (gondolom valamelyik matrix szar) vagy 5x akkora meretu meg ilyenek. de mondjuk 20 filebol 1-nel van hiba, es mindig mas jellegu. megvan a 2000 novemberben forditott linuxos binarisom, az jol mukodik ugyanazzal az inputtal, es ugyanabbol a forrasbol most ujra forditva ujabb gcc-vel meg nem.
> REVERSE_BYTEORDER be van kapcsolva
most nincs. anno portoltam SGI irixre is, asszem amiatt kerult bele.
> uint32_t jobb dword helyett
ugyanaz, arra van typedefelve egy .h fileban.
> (s1*s2)/4 (ugye ha s2 mondjuk 3, es elobb osztja
elvileg (e smegneztem, gyakorlatilag is) mindig 4-el oszthato az input. szoval itt mind1.
> A bitcserelgetesre is van muvelet
tudom persze, de azert is kezdtem azzal hogy ez 25+ eves kod. es nem is linuxos volt eredetileg, dos alatt mas lehetosegek voltak.
> Multithread kornyezet amugy?
dehogy. ez meg dos-ra irt 25+ eves kod, amit anno watcom c-vel, aztan linuxon/irixen/aixen gcc-vel forditottam.
> siman visszaternek az fread-del
igen erre irtam at en is es ugy mukodik jol, csak kivancsi lennek mi a fenti kodban a hiba... mert regen az is ment :)
- A hozzászóláshoz be kell jelentkezni
es neha el van fordulva 90 fokkal (gondolom valamelyik matrix szar) vagy 5x akkora meretu meg ilyenek
Akkor nem hinnem hogy itt ebben a kodreszletben lesz a hiba... ha egy float stream-be akarcsak egy bithiba csuszik, akkor teljesen osszeomlik egy ilyen modell, nemhogy "ja, csak el van forgatva", vagy "ja, kicsit nagyobb de hasonlo az eredetihez". Ott nezd meg ahol az inline hivas tortenik. Vagy probald ki azt hogy ezt a fuggvenyt kiteszed egy masik *.c fileba, ugy forditod ossze a kettot hogy meg veletlenul se lehessen inline optimalizacio es ne legyen semmi side effect-je barmi code reordering es/vagy interleavingnak. Nem kizart hogy a printf() megakadalyozza ezutobbit, es akkor ugy mar jo, egyebkent meg annyira cafatokra optimalizalhato hogy a hivo oldalon valami bug beszivarog oda oszt kesz is a baj.
- A hozzászóláshoz be kell jelentkezni
nekem is fura. amugy van olyan model ami total szet van esve, 1 van aahol kb 5x akkora lett 1 object (de a tobbi obj jo), meg van egy ami el van fordulva. az elfordultast akar az is okozhatna ha el van csuszva 1-el, igy az x-bol y lesz, az y-bol z stb.
> "ja, csak el van forgatva"
emlekeim szerint a 3ds-ben euler forgatas volt, tehat a tengelyenkenti elforgatasi szog volt tarolva. ha ez kinullazodik, az okozhatja ezt (gondolom a legtobb obj-nel ez eleve 0,0,0 de lehet nehany ahol mondjuk 90,0,0 es ha abbol 0,0,0 lesz akkor elfordul)
a meret elteres is lehet akar abbol hogy az az obj sokkal kozelebb van a "kamerahoz" ezert tunik csak nagynak, ezt meg okozhatja a transzormacios vektor nullazodasa.
> Ott nezd meg ahol az inline hivas tortenik
hat 57 helyrol hivja ezt, rakas chunk tipus van es mindegyikben van nehany call.
> Vagy probald ki azt
az a baj hogy szinte barmit modositok a kodon, megjavul. ezert is gyanaxom gcc bugra, hogy valamit elront optimalizalaskor.
csak arra voltam kivancsi, hogy en neztem be valamit, vagy a kod elvileg jo csak a compiler hulye (vagy mashol van valami bug, ami emiatt triggerelodik)
- A hozzászóláshoz be kell jelentkezni
Egyre erdekesebb ez a problema, tenyleg :)
Akkor azt probalnam meg hogy beolvasas utan visszairnam egy file-ba az egeszet es megnezem hogy hol esik szet, melyik ponton es mi modusul (sima hexdump -v, es a ket hexet tkdiff-fel osszenezni, ilyesmi). Akkor be tudod hatarolni azt a pontot az 57-bol (leszukiteni joesetben 1-re, rosszabb esetben nehanyra) ahol szetcsuszik es a hivo oldalon is korulneznek mindenfele bugok kapcsan.
- A hozzászóláshoz be kell jelentkezni
Koszi a valaszokat! Az afs_fread-et meg betenned ide?
Egyebkent siman lehet az is, hogy a gcc valami SIMD trukkozest probal, es a printf megakadalyozza ebben. De ez persze a masik fuggvenytol is fugg (afs_fread). Ha az egyszeru, akkor lehet ez a gond.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
int afs_fread(void *ptr,int elemsize,int elemno,afs_FILE* f){ int size=elemsize*elemno; // printf("AFS: fread %d x %d, current pos=%d\n",elemsize,elemno,f->pos); if(size>f->size-f->pos) size=f->size-f->pos; memcpy(ptr,f->ptr+f->pos,size); f->pos+=size; return size/elemsize; }
azt hittem fread()-ot itt hivja de nem, az afs_fopen()-nel beolvassa memoriaba az egeszet. gondolom azert lett igy megoldva mert elesben mindig egy nagy tomoritett filebol toltotte be a cuccot, csak fejleszteshez/teszteleshez volt kozvetlen file olvasas.
de nem hiszem hogy ennek sok jelentosege van, ez nem inline es egy kulon lib-ben van.
- A hozzászóláshoz be kell jelentkezni
Ennyit mondjuk siman inline-olhat. (foleg, ha rajon, hogy a size fixen 4, es a memcpy is kioptimalizalhato belole)
szerk: (szerk. utan) akkor nincs inline
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
de mondom es egy kulon lib, masik konyvtarban, kulon forditva... az egeszbol csak a .h filet latja.
- A hozzászóláshoz be kell jelentkezni
Eloszor csak a kodot lattam, arra alapult a hozzaszolasom
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
Generált kódot kiíratni a gcc-vel (azt hiszem tud ilyet) és megnézni mi a különbség a működő és nem működő között? Ha valamit elront, ott látni.
"Az élet tele van kérdésekkel. Az idióták tele vannak válaszokkal."
"Its easier to fool a man than it is to convince they have been fooled"
- A hozzászóláshoz be kell jelentkezni
Tud. gcc -S ha nem tevedek.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
En mondjuk objdump-pal neznem meg, biztos-ami-biztos alapon - de jaja, -S az.
- A hozzászóláshoz be kell jelentkezni
Én azt nem értem, miért van a c deklarálása a ciklusmagon belül. Az mire jó? Az INLINE nagybetű?
Azon tűnődöm, hogy amikor ez inline, akkor bekerül közvetlenül a kódba a hívás helyére. Amikor c-t deklarálod, létrejön adott címen, de engem frusztrál, hogy mi van többszöri hívás esetén. Az &c hivatkozás fordítási időben dönti el c címét, de ennek az inline függvénynek a c változója hova allokálódik? Lehet, a while-on kívülre a függvény elejére tenném valahogy így:
static dword c;
Mert akkor az valahova le van téve, nem akar máshova kerülni, fordítási időben meg lehet álmodni a címét. Vagy a másik lehetőség, hogy ne legyen inline.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
> miért van a c deklarálása a ciklusmagon belül.
eredetileg a while-on kivul volt (de nem static), csak probaltam berakni, de nem valtoztatott semmin.
amugy sima local variable, miert ne lehetne belul?
> Az INLINE nagybetű?
az egy makro. inline-ra van definalva, csak ez a kod eredetileg watcom c-re volt irva es ott _inline kellett (legalabbis ezt hamoztam ki a config.h-bol)
> amikor ez inline, akkor bekerül közvetlenül a kódba a hívás helyére.
igen, igy van. gondolom ezert van hogy csak neha bugos, az esetek nagy reszeben jol mukodik.
- A hozzászóláshoz be kell jelentkezni
Biztos jo a static ide? Nem tudom inline-nal van-e kulonbseg, attol 1 darab valtozo lesz, kb. mint ha globalis lenne. Ha multithreades, abbol igazan kaosz lehet.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
Igazad van, közben gondolkodtam ezen. Ez valójában a hívó függvényben lesz egy lokális változó a stack-en, aminek érzésem szerint fordítási időpen a stack pointerhez képesti offsettje meglesz, futásidőben pedig ez a konstans offset és a stack pointer összeadódik, s a tényleges cím így lesz meg.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Na jo, de hogy szar? :) Nem fut le a byte reverse? Hulyeseg kerul bele? Elobb abbafejezi mint kene? Segfault? Mi ez az afs_ prefix es miert ha "ugyanazt kene csinalnia mint az fread()-nek csak byte reversallal"?
Igy elsore semmi extrat nem latok (az afs_ prefixeken kivul), bar most mar inkabb uint32_t-t irnek ki mindenfele `dword`-ok helyett. De nem is biztos hogy itt van a hiba hanem az afs_fread()-ban is lehetnek meglepetesek, barmi is legyen az :]
Ettol fuggetlenul en inkabb optimalizan csinalnam - szoval egy fread()-del kiolvasod mintha mi sem tortent volna, majd utana johet a reversal. Ha ugy csinalod akkor mit kapsz? Ha nem sajat reversal-t hasznalsz hanem mondjuk ntohl()-t akkor mi tortenik?
- A hozzászóláshoz be kell jelentkezni
+1 joreszt.
Az ntohl valoszinuleg nem lesz jo, pont azokon az architekturakon nem fordit, ahol kene.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
pont azokon az architekturakon nem fordit, ahol kene
Najo, de hol kene? :) LSB-n fordit, MSB-n nem. Lattam mar en is ezt-azt de MSB az manapsag mar annyira nem gyakori... de persze ki tudja.
- A hozzászóláshoz be kell jelentkezni
Epp ezert volt a mondatban a valoszinuleg. Csak Arpi tudja melyik bytesorrend a forditott. Meg azt is, hogy mi az, hogy nem mukodik.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
> Na jo, de hogy szar? :) Hulyeseg kerul bele?
neha (eleg ritkan) nem az kerul a memoriaba mint ami a fileban volt. csak ugye nem tudom kiiratni a rosszat, mert a printf-tol megjavul, nem tudom pontosan mikor es hogy romlik el :)
> Mi ez az afs_ prefix
az egy wrapper, mivel ez nem posix kod volt eredetileg, dos alatt pl. mast hiv, meg tud tomoritett filebol (.afs file, innen a prefix neve) is olvasni stb. esetemben most az fread()-ot hivja 1:1-ben.
> most mar inkabb uint32_t-t irnek ki mindenfele `dword`-ok helyett.
most mar en is... amugy linuxon arra van typedefelve.
> egy fread()-del kiolvasod mintha mi sem tortent volna, majd utana johet a reversal.
en is igy csinalnam, nem is ertem, hogy miert igy lett ez anno megirva. emiatt is gyanus hogy ezt nem is en irtam (tobben dolgoztunk akkor a kodon, bar a nagy resze az en muvem, de ilyet en nem szoktam csinalni, bar fiatal voltam meg es kellett a penz stb)
> Ha nem sajat reversal-t hasznalsz
az most mind1 mert a byteswap resz most nem aktiv (x86on nem kell)
- A hozzászóláshoz be kell jelentkezni
Jobban megnezve, eme kodod nem azt csinalja amit a posix varian opcionalisan byte order cserevel kiegeszitve. Ha elfogy a file, akkor ez 0-t ad vissza, az fread() meg eredetileg ugye kulturaltan annyit ad vissza mennyi a file merete volt (osztva a member merettel). Szoval csak ugy "esz nelkul" nem cserelheted ki ezt a sajat implementaciot egy fread()-re ha fel is hasznalod kesobb a return value-t. Extrem esetben azt is el tudom kepzelni hogy az fread() hivas az valami extra layeren keresztul (VDSO?) van implementalva, es ott esik szet a valami.
- A hozzászóláshoz be kell jelentkezni
> Ha elfogy a file, akkor ez 0-t ad vissza, az fread() meg eredetileg ugye kulturaltan
igen ez jogos eszrevetel, de a gyakorlatban sose fogy el, mert nem hibasak a fileok :) es eleve csak annyit olvas amennyinek ott kell lennie.
nyilvan ez az egesz kod kuka, mert nem optimalis es meg bugos is, csak erdekelt volna hogy hol a hiba... mert en azt nem talalom :)
de nem kizart az se, hogy a bug nem is itt van, csak ez triggereli valahogy (pl. uninitialized valtozo tartalma ettol megvaltozik)
- A hozzászóláshoz be kell jelentkezni
Hiba/EOF esetén nem a sikeres olvasás hosszával kéne visszatérnie 0 helyett ?
Amit nem lehet megirni assemblyben, azt nem lehet megirni.
- A hozzászóláshoz be kell jelentkezni
UPDATE: sikerult megoldani, hogy kiirassam a memoriat a beolvasas utan a jo es a rossz mukodes eseten is, es meglepo modon bytera ugyanaz. tehat nem itt van a hiba... hanem vmi mas bugot triggerel ez eleg viccesen :(
mondjuk eredetileg is valami uninitialized warningot nezegettem es onnan jutottam ebbe a func-ba, szoval vissza kell terni oda ;)
- A hozzászóláshoz be kell jelentkezni
na talan sikerult megtalalni a(z egyik) bunost:
typedef float c_MATRIX[3][4];
static void mat_swap (c_MATRIX a) { /* swap_mat: swap y/z in matrix. */ int i; float tmp; #ifdef ast3d_SWAP_YZ phex(a,sizeof(c_MATRIX)); for (i = 0; i < 3; i++) { /* swap columns */ tmp = a[i][Y]; a[i][Y] = a[i][Z]; a[i][Z] = tmp; } phex(a,sizeof(c_MATRIX)); for (i = 0; i < 4; i++) { /* swap rows */ tmp = a[Y][i]; a[Y][i] = a[Z][i]; a[Z][i] = tmp; } phex(a,sizeof(c_MATRIX)); #endif }
diff, a - a hibas, a + a jo verzio kimenete: (phex kiirja hexaban a memoriat)
24 EE F8 41 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 03 C2 D3 36 20 EE F8 41 00 00 00 00 00 00 00 80 C2 26 31 C2 9B B2 16 37 00 00 00 00
- 24 EE F8 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 3F 00 00 00 00 00 00 00 80 00 00 80 3F 00 00 00 00 00 00 00 00
- 24 EE F8 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80 3F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 3F 00 00 00 00
+ 24 EE F8 41 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 20 EE F8 41 03 C2 D3 36 00 00 00 00 00 00 00 80 9B B2 16 37 C2 26 31 C2 00 00 00 00
+ 24 EE F8 41 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 80 9B B2 16 37 C2 26 31 C2 00 00 00 00 00 00 00 00 20 EE F8 41 03 C2 D3 36 00 00 00 00
- A hozzászóláshoz be kell jelentkezni
Adott esetben Y és Z lehetne paramétere a függvénynek. (Optimális esetben mindkettő 0..2 tartományból.)
- A hozzászóláshoz be kell jelentkezni
azok konstansok:
#define X 0
#define Y 1
#define Z 2
#define W 3
biztos, hogy valami baja a 'mat' valtozoval van. ha ele irom hogy static, akkor jol mukodik. ha volatile-t irok ele akkor maskepp bugzik (majdnem jo de egyik iranyban meg van nyujtva a 3d object). ha atrakom mashova a deklaraciot az nem befolyasol. ha a mat_swap() tartalmat masolom oda fv hivas helyett (ugy latom sehol mashol nem hasznalja ezt ugyse) akkor se jobb:
int i, j; c_MATRIX mat; mat_identity (mat); for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) if (afs_fread_float(&(mat[i][j]), sizeof (float), 1, f) != 1) return ast3d_err_badfile; // mat_swap (mat); #ifdef ast3d_SWAP_YZ phex(mat,sizeof(c_MATRIX)); for (i = 0; i < 3; i++) { /* swap columns */ float tmp = mat[i][Y]; mat[i][Y] = mat[i][Z]; mat[i][Z] = tmp; } phex(mat,sizeof(c_MATRIX)); for (i = 0; i < 4; i++) { /* swap rows */ float tmp = mat[Y][i]; mat[Y][i] = mat[Z][i]; mat[Z][i] = tmp; } phex(mat,sizeof(c_MATRIX)); #endif
- A hozzászóláshoz be kell jelentkezni
Es mi az a phex()?
- A hozzászóláshoz be kell jelentkezni
azzal iratom ki:
static void phex(unsigned char *ptr,int s){
int i;
for(i=0;i<s;i++) printf(" %02X",ptr[i]);
printf("\n");
}
az elso hivasnal (a betoltes utan) meg jo a mat tartalma, de a swappolas utan mar nem.
- A hozzászóláshoz be kell jelentkezni
ize, ha 3x4-es a matrixod akkor miert nem az egeszet toldot fel? miert csak egy 3x3-as almatrixat?
illetve nem tudom mi az a mat_identity(), vagyis csak kicsit sejtem, mert a 3x4-as matrixok vilagaban nincs identitas. ha csak a 3x3as reszebe teszi be a kr-deltat akkor kesz a baj. olyasmirol ne is beszeljunk hogy mi van akkor ha egy 3x3as objektumot var :)
szerk: igen, most fogom fel a fentebbit is, szoval ha static a mat akkor inicializalt a [*][3], ha nem, akkor meg ugye nem: az valodi memoriaszemet lesz az elejen. foleg ha mat_identity sem teszi rendbe (ami ezalapjan eselyes). a volatile meg ugye egy kulon allatfaj :)
- A hozzászóláshoz be kell jelentkezni
mert a fileban csak 3x3 float van. a mat_identity tolti fel az egeszet ezzel:
static c_MATRIX Tidentity = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
};
nem inicializalas hiba, mert a betoltes utan a mat tartalma (mind a 3x4) meg jo minden esetben, a cserebereknel cseszodik csak el. de ha berakok egy printf-et az fread-be akkor az is jo. ez ilyen wtf bug mar.
- A hozzászóláshoz be kell jelentkezni
Hogy tolti fel?
- A hozzászóláshoz be kell jelentkezni
az nem tok mind1?
LOCAL void mat_identity (c_MATRIX out)
{
/*
mat_idenity: make identity matrix.
*/
int16 i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
out[i][j] = Tidentity[i][j];
}
- A hozzászóláshoz be kell jelentkezni
Begépeltem fájlba, de nem látom, hogy mit kellene látnom:
https://github.com/lzsiga/hello-world/blob/master/arpi_esp_mat.c
- A hozzászóláshoz be kell jelentkezni
hat ezt igy nem fogod sztem reprodukalni... kell hozza az fread-es cucc is, meg akkor se jon ki a hiba minden esetben.
majd felrakom az egesz cuccot a githubra valamikor, de egyelore masfel napig tartott mig sikerult egyaltalan buildelni, annyi sok biszbasz libbol es filebol all amikhez 25 eve nem nyult senki, eleg sokat kellett mar javitgatni. ez a 3ds loader csak egy kis resze.
- A hozzászóláshoz be kell jelentkezni
Valgrind nem szór esetleg inicializálatlan változókra vonatkozó üzeneteket?
- A hozzászóláshoz be kell jelentkezni
igy nez ki asm-ben:
az elso 2 'call phex' kozotti resz az erdekes, ott cseszodik el a mat tartalma.
xmm regiszterekkel mokol valamit, de ezt a gnu asm-et sose vagtam, meg az sse utasitasokat se, szoval passz.
movl $0, -168(%rbp) jmp .L184 .L185: movl -168(%rbp), %eax cltq salq $4, %rax addq %rbp, %rax subq $60, %rax movss (%rax), %xmm0 movss %xmm0, -156(%rbp) movl -168(%rbp), %eax cltq salq $4, %rax addq %rbp, %rax subq $56, %rax movss (%rax), %xmm0 movl -168(%rbp), %eax cltq salq $4, %rax addq %rbp, %rax subq $60, %rax movss %xmm0, (%rax) movl -168(%rbp), %eax cltq salq $4, %rax addq %rbp, %rax subq $56, %rax movss -156(%rbp), %xmm0 movss %xmm0, (%rax) addl $1, -168(%rbp) .L184: cmpl $2, -168(%rbp) jle .L185
ez mar tenyleg ilyen wtf... ha a jol mukodo verziot nezem asm-ben, a fenti resz (a 2 phex kozotti ciklus) pont ugyanigy nez ki. de megis mas lesz az eredmeny...
szerk: nem jo, -O4 nelkul futott a -S, -O4-el tok mas de ott kioptimalizalta meg a phex-et is belole ;)
- A hozzászóláshoz be kell jelentkezni
unaligned access problema? ha
c_MATRIX mat __attribute__ ((aligned (16)));
modon deklaralod azt? mondjuk hogy a stack-re hogy tud egyszeruen aligned accesst csinalni az is jo kerdes, de sztem megoldja. bar igen, hogyha automatikus es nem statikus a valtozo akkor minek farassza magat stack-kel ha a regiszterekben is elfer igy vagy ugy... 3 darab xmm{0,1,2}-be elfer az egesz matrix, csak azokon operal, aztan csak akkor irja be memoriaba ha nagyon muszaj.
Nezd meg a mat cimet (printf("%p\n",(void *)(&mat[0][0]));) igy is meg ugy is.
A hexdump alapjan mintha visszairna(?) a foatlobeli 1-eseket (3f800000). Kulon bonusz a -0-ert, de azzal nem kene hogy gond legyen :)
szerk: nem, csak xmm0-t hasznal, de azzal is meg ugy onmagaban rafuthat ilyen alignment dolgokra. nem minthogya x86(_64) eseten ennek valodi hatasa kene hogy legyen, de ez mar ilyen francsetudja dolog :/
- A hozzászóláshoz be kell jelentkezni
az aligned nem segitett rajta.
ezutan beleirtam a prtintf-et, es ettol megjavult :)
c_MATRIX mat;
printf("mat.ptr = %p\n",(void *)(&mat[0][0]));
ha kikommentezem a printf-et akkor nem jo :)
megneztem az -O4-el forditott asm-eket is, teljesen mas a jo es a nem jo verzio, masik xmm regiszterekbe rakja, mas a sorok szama is stb, diff-elve alig talalt azonosat kozte. a phex-et is inlineozta, es olyan mintha parhuzamosan menne a kiiras es az xmm-ek kozotti muveletek.
- A hozzászóláshoz be kell jelentkezni
Ha kikommentezed a printf-et akkor nem lesz szukseg arra hogy a mat a memoriaban legyen, ez idaig oke. Ha nincs a memoriaban akkor mindent az xmm*-okban machinal,es abbol kozvetlenul bontja ki a hexdump-hoz is a karaktereket. Ez is eselyes. Kene egy minimal working example.
Meg azt neznem meg hogy melyk -Ox optimization level valtja ki (en max -O3-ig szoktam elmenni, szoval az most nincs az agyamban hogy az -O4 az mit is kapcsol be).
parhuzamosan menne a kiiras es az xmm-ek kozotti muveletek.
igen, minimalizalja a pipeline stall/bubble allapotok szamanak varhato ertekeit... ez is ertheto
- A hozzászóláshoz be kell jelentkezni
igen en is arra jutottam, hogy xmm-ben van a matrix, ezert a memorias piszkalas nem megy.
> Meg azt neznem meg hogy melyk -Ox optimization level valtja ki
hat ez egy erdekes kerdes. -O3 es -O4 biztosan (nem tudom az O4 mi, en sose hasznaltam, de ennek a makefilejaban az volt).
viszont -O3 nelkul nem fordul le a kod, pontosabban a linker nem talal meg olyan func-okat amik amugy ott vannak... az O3 meg gondolom inlineolja oket es ezert akkor nem is keresi :) ezzel is tervezek majd kuzdeni, de egyelore otletem sincs wtf.
az is erdekes, hogy O3/O4 eseten vannak ilyen warningok, -Ox nelkul viszont nincs:
file_3ds.c:1498:5: warning: ‘pos’ may be used uninitialized [-Wmaybe-uninitialized]
1498 | vec_make (pos[0], pos[1], pos[2], &key->val._vect);
egyebkent iszonyat gaz ez az egesz kod, mar biztos vagyok benne hogy nem en irtam, es ahogy nezem nem is sokban ter el az eredeti CLAX kodjatol, amibol anno forkoltuk:
https://github.com/joric/j3de/blob/master/clax/src/file_3ds.c#L564
- A hozzászóláshoz be kell jelentkezni
Hat, probaltam egy minimal working example-t csinalni a dologbol, de gcc-10 es gcc-12 mellett is hibatlanul fut. Ami mondjuk fura hogy nem inline-olja be a phex-et nekem itten.
Illetve azoknak a warningoknak is utanamennek... nem veletlenul vannak vsz ott, foleg az ilyen inicializalatlan biszbaszok temaban lehet vicces az is.
- A hozzászóláshoz be kell jelentkezni
-M intel paranccsal elvileg tud normális syntax-ot csinálni.
- A hozzászóláshoz be kell jelentkezni
Mit szolnal mondjuk egy ilyenhez? Ha a loop-okat unrollozod, az 3+4 csere. Ebbol 2-t meg tudsz sporolni, ha az Y-Z csereket atlosan hajtod vegre. A gcc-t is valoszinuleg az zavarja meg, hogy beteszi az xmm0-ba, de utana masik iranyba tekered ugyanannak az eredmenyet.
Szivem szerint irnek egy inline cserelo fuggvenyt, de ezek utan nem merek.. :)
static void mat_swap (c_MATRIX a)
{
/*
swap_mat: swap y/z in matrix.
*/
int i;
float tmp;
#ifdef ast3d_SWAP_YZ
phex(a,sizeof(c_MATRIX));
// horizontal swap
tmp = a[X][Y]; a[X][Y] = a[X][Z]; a[X][Z] = tmp;
// vertical swaps
tmp = a[Y][X]; a[Y][X] = a[Z][X]; a[Z][X] = tmp;
tmp = a[Y][W]; a[Y][W] = a[Z][W]; a[Z][W] = tmp;
// diagonal swaps
tmp = a[Y][Y]; a[Y][Y] = a[Z][Z]; a[Z][Z] = tmp;
tmp = a[Y][Z]; a[Y][Z] = a[Z][Y]; a[Z][Y] = tmp;
phex(a,sizeof(c_MATRIX));
#endif
}
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
Igenigen, biztos lehet optimalizalni a dolgot de az alapproblema itten hogy miert is nem megy az erdeti kod :]
- A hozzászóláshoz be kell jelentkezni
le tudod buildeni/futtatni ASAN+UBSAN-el? hatha kidob valami hasznosat...
- A hozzászóláshoz be kell jelentkezni