devedse / DeveMazeGeneratorCore

This is the new version of my maze generator, now made with .NET Core.
MIT License
7 stars 2 forks source link

just dropping by because im stuck on my project now, wanan share the UI vs bk thread stuff producer consumer pattern i learned painfully in case it helps you out. #14

Closed damian-666 closed 1 year ago

damian-666 commented 1 year ago

Hello, not an issue , just gving some advice because i was curious. im stuck on a stupid bug in wpf and my level editor and monogame , and jsut chekcing on how your were dong with monogame. and that UI threada and antiquated game loop, generating models in that... when im stuck i like to jsut help someone else and take a break. i noticed you were trying some paralllet tests on the UI thread butthatt is problematic. se it hink i had suffered this before. FOR MONTHS , when i tried UWP and monogame for the first year wiht MG. im a bit torn begin trying the compute branch but i thnk ill stick wth SIMD and cPU and use use the draw call and GPU just to draw a copy of my model from a sort of cache frendly ECS, or any sort of display list data. copying costs amost nothing compared wiht thread syncing. as the bepu physic guy says its just too much work to do GPU parallelism.

if you do a Parallelfor on the main UI thread you may not get the results you want. https://stackoverflow.com/questions/69964184/calling-ui-thread-from-parallel-loop-using-dispacher-begininvoke here an example, the guy suggestes to "Producer /Consumer" the whole async TAsk stuff is madness. I just run a separate worker thread and copy the frame to a buffer when itss done writeing the fraem in RAM. then when it needs to be rendnered the draw draws the copy... ( UNLESS YOU are using callbacks gthat use GPU stuff) then i dont konw what to . advise since MG is only one thread drawing

The monogame game loop is from the daays of one thread games. first issuel , The timer aer useless for one framemeasuremnents in real time ( under 16 ms or 60 haz(.. Stopwatch can be off by 16 ms. You can time a Sleep(1) and get1- 16 ms result in windows, simple test..

so #1 [System.Runtime.InteropServices.DllImport("winmm.dll", EntryPoint = "timeBeginPeriod")] public static extern uint timeBeginPeriod(uint uMilliseconds); wrks in windows... next google how to do linxuan and androind is similar and necessary. theres ways in linux, ios and android also to do this. set it to 4.. its enough.. or 1. 16 is enough to skip a whole frame and that will screw up the vsync. its not system wide anyore either.. some people got good timer results because chrome was runing in the background. its was setting it system wide. now its ok to set it per app and not drain battery. set it at last 4ms.. if youare doiing updates on the maze ..

Then i can subract my timer from the decribed Model frames per sec, and sleep fo rthe rest of the tiem. i can set my frame rate to 300 fps, 100, of just dont sleep i get like 4000 on a 8 core basic laptop.. ( physics) drawing at vsync wtih 4 full contact powered ragdolls 27 collding bones, its amazing. wiht dispathcer limiations i was limited to the 60 fps or stuttering in locks and deatlocks. and im not even exploiting SIMD yet. Butthats why i want to say off the GPGPU and the UI thread because its for UI and drawngs and its crazy naunced. when you are on the bk thread you can simD and vectorize and go crazy with that. so tis either one thread and gpcomute.. or simd and producer consumer.. Bepu physic choose the simd routte..an a long blog post. I dont even use SIMD and i get blazing speeds now that im off the crazy UI thread stuff..

I dont mean to meddlle and i dont undersand your mdoel full but seems like you want the producer consumer pattern and dont really do anything on the maze genUI thread in MG.. i dont use Update.. i dont block dispatchers or UI ever.. aftre long mucking around , I run a background thread that runs a physics simulation. I try never to lock it.. When im done I copy all the model data to a buffer.. Then i switch the worker thread to start maing the next frame on the write buffer that swapped to the read one whne its done. The draw can draw the read only model, last maze or creature or whatever since its not bieng writtnen to... whenever its gets called.. via vsyc no locks .. no asyc awaits or whataever thast stuff is... no semaphores either really. i had to do this for android, or it just never even ran. ususualy i generate 400 frames before it draws one.. i need to because my physics will tunnel if i dont. they dont need to see the inbetweenframes.

you can Parallef.For then anywere on the background thread bgame loop.. without any weird issues. just spawn a worker thread loop as your game loop run it till sleep or pause or exit.. . you can even poll the ui keystates as height rates . or do that on update. ... put a timer in it and and sleep if its going way too fast , heating the phone, and you want to show the maze being progressively made.. if im doing tests is full throttle.

I just run a worker thread and copy the frame to a buffer wiht all it needs to be rendnered ( UNLESS YOU are using callbacks gthat use GPU stuff) hen i dont konw what to advice since MG is only one thread drawing.

when started with monogame i spend MONTHS tring to get a stable frame rate. now i got 4000 fps ro whateve i want and smmoth and no locks to waits and UI weirdness.

I dont mean to meddlle and i dont undersand your mdoel but seems lie you want the producer consumer pattern and dont do anything on the UI thrad in MG.. i dont use Update.. i dont blockit .. I run a background thread that runs a physics simulation. I try never to lock it.. When im done I copy all the model data to a buffer.. Then i switch the worker thread to start maing the next frame. The draw can draw the last maze or creature or whatever since its not bieng writtnen to...

when started with monogame i spend MONTHS tring to get a stable frame rate. now. I run a backgound thread at 4000 fps and draw at 60 hz.... none of the sampels show a real game loop for anthing athat uses the cpu for more tant a a pixel art one thread game. its just a render framework fo r11 platfroms. it makes u do all hte rest..

devedse commented 1 year ago

Hey @damian-666 ,

Thanks for your ideas. I think currently for me the area where' I'm doing a long running operation on the main (game) thread is when I generate a new maze. This does happen only when the character has finished walking to the end of the maze or when the game starts (or when you press R / change the size of the maze).

The only other place I could think of I'm doing some more complex operations is the LineOfSightDeterminer, but that code is only called when you're activating camera 3 I think.

So with this in mind I don't think this will change the FPS when the character is walking through the maze itself in the normal camera's.

I would like to implement this though at one point, that when a maze "finishes" the game just shows "Loading new maze 1%, 2%, ... 100%" while you can still see the existing maze. So it's a good idea I'd have to spend some time on someday soon (tm).

damian-666 commented 1 year ago

i was just curious because i saw the vid on that webside... ith theh mazes that were extremely hires.. deep zoom or whatever and it was drawngas as generat the maze.. so you could be olk.. but the callback might give u troubles. but stll the ui therad .. it sucks to spawn child threads from it because of retentrancy stuff.. monogaem has no samples of a game loop for a real game for 2 processors. when XNA came out , yes, but now, there desont even exst one processor system execpt on a nokia candy bar phone mabye.

now m in helll becasue of wpf core and embedding Monogame.. so i have ot deal with the dispatcher thread context. jsut because i chose that to do level edtiongn in wpf long ago.. so im a bit n deep sh*TT even if my game gets 4000 fps. as a netcore app... i still have to mantain this old level editor.... when you spawn thread off teh worker then you dont get weird aycnt Wait ret result crap to to whic is just mind bogglng. async await get result, i usggest dont bother .. so that prodcuer consumer pattern just openned allthe doors for me... un tryinng to now get it n my wpf code because all the timers and locks i need also depended on that timerresolution too. I think Moongamae should have a sample of producer / consumer pattern but peope are too competitive to share when they figured it out.. i dont care beause games are judge on art and playability.

btw im curious about your maze beause i have to use grids now for water and gas simulations and some of the gass has to pass thin openings an channels... i am mixing vector collison and raster advection so now im in this chimera multiphysics stuff mabye ill study it sometime..

now im starting to learn how to get off the virutal methods and into SIMD.. so i read what Bepu physics guy says and why he decide not to go tht GPGPU route..
heres what drove me to stop tring gpgpu stuff or gett far nto computebance of mg. snce i saw 1000x faster stuff i got exited but then you got 6 idle gpu cores.. and CPU are easer to branch code n and prototype.

https://www.bepuentertainment.com/blog/2019/1/16/-but-gpus-arent-always-the-right-choice here s an except ... from bepu... https://github.com/bepu/bepuphysics2/blob/master/Documentation/Substepping.md (Note that attempting to dispatch multithreaded work from the same IThreadDispatcher instance that dispatched the solver's workers requires that the IThreadDispatcher implementation is reentrant. The BepuUtilities.ThreadDispatcher is not.)

and he mentons Callbacks The solver exposes events that fire at the beginning and end of each substep: SubstepStarted and SubstepEnded. These events are called from worker thread 0 in the solver's thread dispatch; the dispatch does not end in between substeps to keep overhead low.

anwways thnansk for sharing code...jsut trying to save people months i suffered goign the wrong way... life is too short!!! i like Monogame beause i cange targe x platforms and i like that they keeep it simple , just rendering... if i leanr SIMD and CPU and a litte big about shaders , i dont care what they do or dont do anymore so i try to stay out of the core discusson. now.. its too hard to move forward whle maintainngin 11 GPU targets and limted to Net5. Net 7 is where the SIM stuff just started..

also ther is a new ECS that uses no virtual calls or polymorphoism... all structs , array, and comprosition so i mght rebuild by ECS more like that someday after i ship my existing game whihc is fas enough anyways... or else i never will..