C/C++, inclusione di vettori e matrici nello standard

0

Proposta per C++14 per tipi SIMD: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3759.html
Discussione al riguardo: https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/nDFuHccBYjI
Progetto che propongono di integrare nello standard: https://github.com/VcDevel/Vc

Also relevant: http://www.reedbeta.com/blog/on-vector-math-libraries/ (nei commenti ne parlano)

Una delle più grandi mancanze di C è l’operator overloading per tipi matematici come vettori e matrici, che sono comunemente usati nel gamedev e nella grafica. Farlo a mano come in c++ porta a non essere sicuri del significato degli operatori, e qualche programmatore, tipo Quelsolaar (Eskil Steenberg), se ne lamenta e dice che preferisce di gran lunga usare funzioni, dicendo che non è affatto scomodo. Ci ho provato, ed è scomodo al cazzo se lo confronti con avere gli operatori. Non tanto per il numero di caratteri da scrivere, quanto per la leggibilità del codice. Un’espressione matematica diventa una serie di scritte incrociate illeggibili. Per risolvere il problema del sapere che fanno gli operatori secondo me sarebbe utile poter chiamare le funzioni con 2 parametri come operatori, come fa Jonathan blow in JAI, ma senza caratteri speciali. Esempio:

float dot( V2 v0, V2 v1);
float r = v0 dot v1;

Il problema qui sarebbe la precedenza degli operatori, ma io mi accontenterei di dargli precedenza uguale e usare parentesi. Poi si potrebbe stabilirne una con una qualche sintassi, ma potrebbe essere un casino. Per farlo allo stato attuale stavo pensando di farmi delle macro ( 😉 ) del tipo:

#define op_dot *
#define op_cross ^
#define op_hadamard &
V2 operator & ( V2 v0, V2 v1 )
{
    V2 ret = {v0.x * v1.x, v0.y * v0.y};
    return ret;
}
V2 hadamard( V2 v0, V2 v1 )
{
    V2 ret = v0 op_hadamard v1;
    return ret;
}
V2 h = v0 op_hadamard v1;

Non sarebbe male se mettessero una cosa del genere nello standard C.
Clang ha un’estensione che da tipi vettori e matrici con relativi operatori, non so se sia specifica per SIMD, ma ci vuol poco al compilatore a usare SIMD in questi casi. La proposta per C++14 che vi ho linkato è specifica per le SIMD, il che mi pare complesso per la differenza tra gli hardware (differenza che non conosco). Per me basterebbe aggiungere tipi V2,V3,V4, M3, M34, M4 e operatori e funzioni come in GLSL. Sarebbe poi il compilatore a usare le SIMD quando possibile. Ah lo swizzling sarebbe figo da avere, come in GLSL.

Secondo la mia modestissima opinione, dato che sto scrivendo parecchio codice in CG/HLSL, Matlab e C++, non è così scomodo avere funzioni per operazioni di cross e dot product (non sto usando hadamard al momento)

Il vantaggio di avere operator overload per tutto è che sicuramente più immediato leggere le formule in “matematichese”, mentre il vantaggio di avere le funzioni è per coerenza con altri linguaggi e librerie (un esempio su tutti, gli shader).
Il problema della lettura Io risolvo con i commenti: scrivo un commento in latex sopra il codice che interessa le formule ed è meglio di qualsiasi operator overload.

psicomante Scrivere un commento sopra non risolve il problema, anzi ne crea un altro. Se hai un errore nel codice e l’espressione derivante non è solidale con il commento rischi di non trovare il bug per molto tempo. Inoltre devi stare attento ad aggiornare il commento ogni volta che cambi il codice e viceversa. Il codice dovrebbe essere leggibile e non dovrebbero servire commenti, se non in casi particolari.

Ma infatti il problema non e’ dot e cross che vanno benissimo come funzioni, ma per operazioni piu’ basilari tipo + – / * che diventano veramente dolorose da scrivere senza il supporto a overload operators.

Mi sono trovato in questa situazione giocando a farmi un motore 3D/fisico in Go, che non ha operator overloading e.. non e’ bello.

Comments are closed.