Announcement

Collapse
No announcement yet.

New Core Feature: Async Framework (Master Branch and 4.8)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

    #31
    Originally posted by iniside View Post
    Is there any info about UObject being able to be accessed from other threads/run functions on other threads and being created from other threads ?
    The last information about it I found is from 2014 and it "working on making UObject thread safe". but it doesn't seem to have any progress since then.
    I'd like to know if anything has changed as well... Last time I checked UObjects can't be touched outside game thread.
    | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

    Comment


      #32
      UObject creation and destruction is thread-safe. However, this doesn't mean that UObject usage in general is thread-safe. You are still responsible for writing thread-safe code yourself. It is probably safe to assume that none of the built-in methods are thread-safe.
      Gerke Max Preussner | UE4 Programming Consultant

      Logo
      Follow me on Github | Goodreads | Linkedin | Pinterest | SlideShare | Twitter.
      Chat with me as gmpreussner on Discord.

      Comment


        #33
        [MENTION=1986]gmpreussner[/MENTION], can you elaborate a bit on what that means in practice?

        You're saying it's okay to call NewObject outside of the game thread? If so that's news to me. Is there some synchronization going on to prevent the GC from snaffling the object before we have chance to root it or reference it somewhere?

        And then what about safely setting a UObject* property somewhere, since the GC could be reading those at any time, right?

        I'd previously assumed the only potentially safe way to use a UObject in a background thread was to pass a pointer from the game thread to an existing object that you know is guaranteed to remain alive, and even then to pretty much stick to only accessing code and member variables that we control ourselves.

        Comment


          #34
          I'm really interested in this feature. I am trying to create 8 TaskGraphs and in each one, I create 4 TaskGraphs. Do you think this way may cause some problems? So can I create some TaskGraphs in another TaskGraph?
          Last edited by YuchenMei; 06-13-2017, 08:28 AM.
          My Programming Blog

          Comment


            #35
            Should I used Async when I don't care about the result?
            George Rolfe.
            Technical Coordinator at Orbit Solutions Pty Ltd.

            Comment


              #36
              Any news on the continuations? Coming from web programming and C# (where we already have both chained promises and the awesome async-await), it feels incredibly hard and time-consuming to implement asynchronous and optionally-parallel computations in UE4. We're in C++, though, and I understand how hard it most certainly is to implement such a thing so that it works on at least most platforms consistently.

              Question - I understand it's not desirable and safe to change any properties of uobjects in async tasks and other threads, but how about just accessing their properites?
              Example: I have a complex perception and goal prioritization AI system, which takes all the available (overlapping, for example) actors, extracts possible actions from their components and ranks them based on their weight (which is determined by const function calls, so no side effects, only calculations). In crowds, it becomes incredibly slow to spawn any new AIs, cause they start studying and ranking all 100+ of other guys around them and pretty much freeze the game thread.

              I feel like it would be a perfect thing to offload the whole evaluation on separate thread(s) and call delegate to make AI decision as soon as all evaluation is done. However, the evaluation "reads" overlaps, actor locations etc. I have not yet attempted to try and make it work, but do you think there are any problems with this approach?
              Core i7-8700K @ 4.8 GHz
              2x ASUS GTX 970 STRIX SLI @ 1450/7600
              Z370 AORUS Gaming 7
              32 GB G.Skill Trident DDR4-3200
              EVGA 850 G2
              850 Evo 500 + 840 Evo 256

              Comment


                #37
                I've found it impossible to get any real information out of Epic staff on even just a basic idea of what is and isn't safe regarding UObjects and threads.

                Still, I think it's fair to say that even reading properties isn't safe to do from another thread unless those properties are your own and you can guarantee they're not being written to on some other thread. In the case of things like component transforms this clearly isn't the case - the engine may be updating them, so you can't just read them from a background thread. What you'd want to do is have some code being run on the game thread that grabs the data you need and hands a copy of it off to the worker thread to process.

                Comment


                  #38
                  What you can't do:

                  - Create Objects.
                  - Destroy Objects.
                  - Change Object Allocation Size.
                  - Invoke or Broadcast Delegates.
                  - Broadcast BP Events that belong to Game Thread.
                  - Create Slate Widgets, etc, etc...


                  What you CAN do:

                  Setup your thread/task to avoid 'race condition'.
                  Then you can do things like...

                  - Message Game Thread to create a UObject "when possible".
                  - The same to destroy an Object, add a message to queue.
                  - Directly change allocation size and value of UProperty containers when using UProperty Helpers.
                  - Message Game Thread to invoke Delegates "when ready".

                  Depending on the size of your "task", when you message Game Thread, it may lock or slowdown if your thread is sending tons of messages every frame because then they won't in essence be asynchronous threads anymore.
                  | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                  Comment


                    #39
                    Care to reference where you're getting this information from? I'm curious because re. creation/destruction you've directly contradicted what an Epic engineer has written just a few posts up. Also the idea that you can't invoke delegates outside of the game thread makes no sense at all.

                    Comment


                      #40
                      With "UObject" I mean AActors, UActorComponents, etc.. these more complex classes.
                      If you invoke multicast delegates from outside game's thread that runs functions within Game Thread all you'll get is a call to a check(IsInGameThread()) and Unreal gonna crash.

                      I am currently writing multi-threaded modules (some for plugins too).
                      If you create basic UObjects, it's fine, but more complex classes will pretty much always cause fatal issues.
                      | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                      Comment


                        #41
                        Originally posted by BrUnO XaVIeR View Post
                        What you can't do:

                        - Create Objects.
                        - Destroy Objects.
                        - Change Object Allocation Size.
                        - Invoke or Broadcast Delegates.
                        - Broadcast BP Events that belong to Game Thread.
                        - Create Slate Widgets, etc, etc...


                        What you CAN do:

                        Setup your thread/task to avoid 'race condition'.
                        Then you can do things like...

                        - Message Game Thread to create a UObject "when possible".
                        - The same to destroy an Object, add a message to queue.
                        - Directly change allocation size and value of UProperty containers when using UProperty Helpers.
                        - Message Game Thread to invoke Delegates "when ready".

                        Depending on the size of your "task", when you message Game Thread, it may lock or slowdown if your thread is sending tons of messages every frame because then they won't in essence be asynchronous threads anymore.
                        Can you elaborate? How do you "message" game thread to create AActors, for example? Is there a pipe/stream messaging API already built-in ue4, or are you making your own?
                        Core i7-8700K @ 4.8 GHz
                        2x ASUS GTX 970 STRIX SLI @ 1450/7600
                        Z370 AORUS Gaming 7
                        32 GB G.Skill Trident DDR4-3200
                        EVGA 850 G2
                        850 Evo 500 + 840 Evo 256

                        Comment


                          #42
                          Originally posted by Lordink View Post

                          Can you elaborate? How do you "message" game thread to create AActors, for example? Is there a pipe/stream messaging API already built-in ue4, or are you making your own?
                          I built for my projects a class with static mechanisms and static delegates that can be linked from AsyncTasks using "FSimpleDelegate::CreateStatic" like Mike Preussner suggested we should do in this same thread.

                          There's usage samples in engine code, they are really simple to use together with AsyncTasks.
                          They wrap parameters into structs and send them to "named" Game Thread, but I usually send object pointers instead because I need access to UProperty* objects (when I read/write user defined blueprint structs or create new UObjects within the DoWork() function.
                          | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                          Comment


                            #43
                            I use a simple bool set/reset in DoWork() what can be checked in the caller class when it has a tick function, probably not the most elegant but works.
                            As an example, I reworked a plugin to make cover calculations async:
                            https://github.com/s-ivan/CoverGener...oversAsync.cpp
                            An example of using delegates would be cool. Probably I could do it, if I were not so lazy...
                            "Age of Total Heroes" - RTS Pathfinding and Movement System for UE4
                            RTS Camera C++ Tutorial

                            Comment


                              #44
                              bump


                              Error
                              • Please enter a message with at least 10 characters (please_enter_message_x_chars)



                              Comment

                              Working...
                              X