Quindi sto essenzialmente cercando di implementare un'Aria Native Extension che esegue la simulazione fisica in C con le interfacce tramite Actionscript.Threading Box2D con pthreads
Ho passato un bel po 'di iterazioni che elencherò di seguito per interesse e sono a quello che penso possa essere il mio ultimo tentativo di farlo funzionare in un modo più performante.
In definitiva sto cercando aiuto su come impostare un ambiente di threading per eseguire la simulazione di Box2D su un thread separato e quindi eseguire il polling dello stato in AS3.
Metodi:
- Brute force:
In questo metodo ho semplicemente mettere in C da AS3 e dirgli di creare un mondo e passarlo alcune scatole da aggiungere al questo mondo. Ogni frame in AS3, chiamo in C per dire al mondo di Step, quindi eseguo un ciclo attraverso tutti i corpi del mondo, ottengo la loro posizione e rotazione, li converto in oggetti actionscript e li metto in un array actionscript e poi li rimando a AS3. Una volta lì, faccio un ciclo attraverso l'array di restituzione e assegna quei valori di rotazione e posizione ai miei sprite in modo che vengano aggiornati visivamente.
I risultati sono in realtà abbastanza buoni con circa 116 caselle aggiunte prima del framerate. Questo è paragonato a 30 box in una pura implementazione AS3. Nota che queste statistiche sono in modalità Debug. In modalità di rilascio, entrambi raggiungono circa 120 caselle. C'è poca differenza tra l'implementazione AS3 e l'implementazione dell'estensione nativa.
- ByteArray condivisione
Al fine di migliorare le prestazioni ho deciso che sarebbe una buona idea per cercare di limitare la quantità di dati che vengono schierato tra C e AS3 . Il supporto di ANE che condivide lo spazio di memoria di un array di byte e quindi vorrei inviare il ByteArray creato in AS3 a C e avere C semplicemente aggiornare ByteArray. Questo ci risparmia dal dover costruire oggetti AS3 in C e passarli indietro. Ogni frame, AS3 ha semplicemente bisogno di scorrere attraverso il suo ByteArray e vedere cosa C ha scritto in esso e quindi assegnare quei valori agli sprite per impostare lo stato visivo.
I risultati qui sono purtroppo circa lo stesso. I miglioramenti sono solo marginali.
- Impostazione Oggetto Diretto Da C
Un'altra cosa ANE di sono in grado di sta impostando la proprietà di un oggetto che vive in AS3. In questo senso ho mirato a eliminare il sovraccarico del passaggio dei dati in AS3, il looping dei corpi per raccogliere i dati in C e il looping in AS3 per assegnare i valori. Ho modificato direttamente il codice di Box2D in modo che quando i valori fossero cambiati scrivesse i nuovi valori di x, y, di rotazione direttamente sullo Sprite corrispondente.
I risultati sono sorprendenti a quantità molto ridotte di oggetti poiché la chiamata per impostare queste proprietà è ben al di sotto di un millisecondo. Il problema è che questo scala in modo lineare e intorno a circa 90 oggetti, il sovraccarico è troppo severo e le cose iniziano a rallentare.
- Threading
A questo punto ero un po 'perplesso. C'è un sovraccarico nei dati di marshalling, c'è un costo in C per l'iterazione e la costruzione dei dati da restituire e c'è un costo in AS3 per l'iterazione per assegnare valori agli sprite.
Ovviamente ci deve essere un compromesso quindi la mia soluzione attuale è la migliore che riesca a trovare per ora.
Sul lato AS3 chiamate in C per creare il vostro mondo, chiamate per aggiungere una casella a quel mondo e chiamate per dire a C che volete un aggiornamento dei vostri dati. Quando le scatole vengono create in AS3 ottengono un ID univoco e sono memorizzate in un dizionario con la chiave che rappresenta l'id.
Sul lato C, il mondo viene creato e viene generato un nuovo pthread per eseguire il passaggio. Simula essenzialmente il mondo su un altro thread. Dopo averlo fatto, assembla tutti i dati e li scrive in un doppio array. Quindi lo fa ancora e ancora e ancora. Semplicemente simula per sempre fondamentalmente sul proprio thread.
Quando chiamiamo in C per aggiungere una nuova casella, ho bisogno di creare una nuova casella e aggiungerla a quel mondo. Dal momento che il mondo sta facendo un passo questo potrebbe causare problemi, il che significa che ho bisogno di usare i mutex, ne sono abbastanza sicuro.
La stessa cosa quando chiamiamo per ottenere i valori aggiornati in AIR, voglio fare una memcpy dall'array di doubles nel mio AS3 bytearray e quindi passare attraverso il bytearray per impostare i valori sul visual.
I mutex mi davano fastidio così ho praticamente implementato la mia, che potete vedere qui sotto ... e ridere :)
Tuttavia funziona, semplicemente non veloce come vorrei anche. Verso il 90 rallentiamo di nuovo.
Qualcuno ha qualche idea o suggerimento? Sarebbe molto apprezzato!
codice C
Il parser stava comportando in modo ho incollato qui: http://pastebin.com/eBQGuGJX
Codice AS3
Stessa cosa con il parser. Ho incluso solo il metodo pertinente che riguarda ogni frame in AS3. http://pastebin.com/R1Qs2Tyt
Ho la sensazione che questo è il sanguinamento bordo basta che non si trovano molta assistenza ovunque :) Sono anche perplesso sul motivo per cui le discussioni avrebbero aiutato. Poiché ogni passo del mondo ha bisogno delle informazioni dall'ultimo passaggio, non possono essere eseguite in parallelo, e l'esecuzione della parte C in un thread non aiuta se il collo di bottiglia è il trasferimento di informazioni su AS3. All'interno di una fase del mondo è possibile eseguire contemporaneamente piccole sezioni del processo, ma il guadagno in termini di prestazioni è piuttosto ridotto e il consenso generale sembra essere che sia più vantaggioso utilizzare core aggiuntivi per il rendering o qualcos'altro. – iforce2d
Grazie iforce2d. Sì, non ero sicuro di ottenere una risposta di per sé, ma speravo di poter ulteriormente approfondire la discussione su approcci come questo o collegamenti a materiale rilevante per spiegazioni più approfondite. La mia speranza era che la simulazione potesse essere semplicemente eseguita lungo il proprio thread e il rendering sarebbe appena entrato e tirato l'ultima "istantanea" delle posizioni dell'oggetto e usarlo per renderizzare. – Jon
+1 per la domanda/articolo molto interessante – Ryan