addy914

Members
  • Content count

    43
  • Joined

  • Last visited

Community Reputation

158 Neutral

About addy914

  • Rank
    Member
  1. C++ Thread safety

    Honestly, I think I will stick with having my 7 threads that each do their own task. I do like the idea of passing data and each thing having their own copy, that is very good. It may take a small bit of extra memory, but that will make up for the faster processing. Threadpools aren't going to exactly help me. Since I planned on having the rendering thread in the threadpool structure, it does not help render any faster. The input thread shouldn't be too overhauled with work since it just takes data from the system. I doubt the network thread will be working too hard because it just takes packets and passes them to the form and usually those packets aren't doing any extraneous work. The content loading is probably the only thread that is working hard. But there is 4 threads, each one sits and waits for an event from a queue, and when it does, it will wake up and load it. That's it. If one is holding, then the rest will pick up. Yes, threadpools might be great for servers but I doubt it's for a client. It seems like its just not going to fit into my game. I doubt 8-cores is very common in computers. I'm sure if people have them, then lots of the time, they aren't actually using all 8 cores in one game. I believe if I just used a threadpool and it would only have two threads(I have a duo core), then it would end up worse than what I have now. I would have to set a timer for network events and rendering. If all that is being processed on only one thread, and the other thread is for rendering with OpenGL, then it would get backed up, and my networking/rendering would get delayed and its just like a single-threaded thread all over again. I think having 7 threads would be fine with anything under 8-cores performance wise, because I have done this before and it works pretty smoothly(I used shared_ptr, so it's probably really slow to what it could be), and because the CPU will handle what thread is ran and when it is. Now, if you have 8 cores, you will most likely be running at maximum effeciency with this application, but anything more, you would run at the same performance. That is okay though, if it runs smooth, then who cares if it runs smooth again? I am having a set FPS, so whats the point if I enable it on more threads, it would just draw it the same. Ill earlier in the topic stated that they got 50000 objects to successfully draw on one thread. With that statistic, I'm good with the way he did it. I doubt I will ever need to draw that many in my game. I believe he was drawing 3D objects, I plan to only do 2D in this game for now, so that number is probably increased. Also, you have to account for the other processes being run on the computer. If someone has more than 8 cores(highly unlikely), then he probably has a lot of those being used as well. You don't want to be that one application that steals all of his cores and sky-rockets his CPU. Ill, the example for a task you gave was a AI think step. I am working on a client that will connect to a server, the AI think step would be done through the server, which I agree servers would probably be perfect for threadpools. The case where AIs think step will be performed client-side, is in a single-player game. I agree that they should be ran concurrently and that will save time. I think if I were to make a single-player game, I probably would have my designated threads do what they are specialized for, and then have additional threads for the AI threads. I couldn't make the whole client have threadpools because their data would conflict. I get what you mean by a AIs think step, because it will just affect that AI and won't have to worry about synchronizing data. I would most likely assign a set amount of threads for tasks that should be performed concurrently if I ever was to work on a single-player game. That thread would just sleep until there was something in the queue to perform.
  2. C++ Thread safety

    I seem to be having trouble picturing how I will achieve threadpools. I'm not sure how to synchronize the data still. If I have a thread pool(decided I will dedicate the first thread to rendering at a constant FPS), and then have the other threads reading tasks from a queue and running them, what if two network packets come in and access the same data? I'm a bit confused on how I should store data. You mentioned that the 'task' should contain the data it needs already? I am a bit confused, but I will show what I am thinking of doing. Thread pool will contain x threads where x is the number of cores. It has to be at least two. The first thread will be for rendering graphics. I will probably have some type of boolean to set to draw, not sure how yet. Then the other threads will read from tasks from a queue. I will have a timer set at a constant speed for checking network packets, and a timer for drawing graphics. Once the timer is hit, if its a network check, it will add a task to the queue to inform that it checks for data. If its a render hit, then it will set some sort of draw boolean. Now, the only confusing part is what exactly do I do when I get a task from the thread? I am just imagining all this for now until I get a clear idea of how it will work. I don't want to just dive in programming yet
  3. C++ Thread safety

    I see what you mean now, it does sound efficient. i think I am confused on what your definition of a 'task' is? Can you elaborate and maybe give an example of what a task is?
  4. C++ Thread safety

    [quote name='Hodgman' timestamp='1344321507' post='4966918'] [quote name='addy914' timestamp='1344317977' post='4966910']in the input thread[/quote]Don't think in terms of "threads". Use a framework that abstracts away threads. Instead of having the X thread, Y thread and Z thread, it's much more efficient to run the X tasks across all threads, then the Y tasks across all threads, then the Z tasks across all threads. This makes 100% use out of a single-core machine, or a 24-core machine, whereas the "XYZ thread" system is hard-coded to best perform on a 3-core machine (and even then, certain cores will be much more over-worked than others). Remember, in game engines, the point of using multiple threads is to take advantage of multiple CPU cores. If an operation isn't computationally complex enough to max out a single core, it doesn't need to be burdened with the complexity of multi-threading. Something like "collecting user input" definitely won't be complex enough to warrant having an entire thread dedicated to that single task (unless your user input device is a camera maybe, like the kinnect)! Check out the "effective concurrency" series. The first one is here, and the last one has an index of them all. [/quote] So, you're thinking more like a thread pool with x amount of threads that all take from a thread-safe queue and will perform a task when one enters the queue. That does sound like it'd work a lot better but I am using OpenGL which requires that the context be set in the thread. I could make a new context for each thread and set it there. I also have the question, how am I going to have variables per thread, if the threads will be running virtually any time of task? [quote name='Cygon' timestamp='1344327714' post='4966943'] Windows CriticalSections and Linux futexes are usually the best option you have. If contention is low, they will burn a minimal number of CPU cycles (if no other thread is in the CriticalSection/futex, it's the price of a function call, then it will do a busy loop, repeatedly checking whether the CriticalSection/futex can be entered and only then will the thread be put to sleep (which is by comparison extremely expensive since it has to wait until the thread scheduler to allocate it another time slice when the CriticalSection/futex becomes free again). I would recommend using std::mutex if you can (Visual Studio 2012 RC, GCC 4.6+). It's portable and provides its own RAII scopes (std::lock_guard). There's also the possibility of writing lock-free data structures. These are mostly based on an operation called "compare and exchange" which all CPUs in the last 10 years have supported as an atomic operation (one that can't be preempted by another thread in the middle). There is a golden window of contention where lock-free data structures are much faster than CriticalSections/futexes - they're slightly slower at zero contention and tend to completely mess up under very high contention. They're also incredibly difficult to write even after years of experience with instruction reordering, cache lines and compiler behaviors. And they're a patent minefield. Thread-local storage is the equivalent of copying your data to each thread. You seem to have one variable, but each thread reading or writing it is in fact reading a variable of its own. Sometimes useful, often confusing. Smart pointers cannot help you with threading in any way. They cannot do any synchronization simply because when you call a method on the object the smart pointer is referencing, the smart pointer's function call operator will be invoked to return the address of the object. It could enter a CriticalSection/futex there, but there's no place where it could leave it again. If a smart pointer is thread-safe, that means it won't blow up if you, for example, copy it while it's being destroying (a normal smart pointer, for example, grab the wrapped pointer, then increment the reference count - which might just have been decremented to zero between the two operations by another thread that is now destroying the object behind the wrapped pointer). Hint: Boost::shared_ptr and std::shared_ptr are not thread-safe. Boost's page on shared_ptr thread safety makes it sound a bit as if, but they're only saying that any number of threads can read the shared_ptr (dereference it) - which holds true for any C++ object - but a write (assigning, reference count adjustment) must never happen at the same time. If you have the chance to use C++11 check out std::future to parallelize tasks in a simple way. Boost, Win32 and WinRT also offer thread pools (here's a small code snippet using the Win32 thread pool API: WindowsThreadPool.cpp) which are great of you can partition work into equal chunks (number of chunks = std::thread::hardware_concurrency ideally). Depending on the specific thread pool implementation, you can even do blocking tasks in those threads (the Windows thread pool will vastly overcommit the CPU based on some heuristics and it has a flag through which you can hint that you plan to block one of its threads for a longer time). [/quote] I originally was going to use EnterCriticalSection but I don't like that 'if contention is low'. Contention would most likely be high in my application. Yeah, a lot of systems do have atomic operations for different variable types, but it just all depends upon the system. I am checking out future and promise now, they do sound interesting. [quote name='BeerNutts' timestamp='1344348097' post='4967012'] (Since no-one else has asked yet, I'll be "that guy"). Do you need multiple threads? Is your game going to be so processor intensive that it would cause slow-downs if you have multiple threads? Or do you just want to use multiple threads for fun? A vast majority of hobbyist games don't need multiple-threads (I'd guess only ~5%, if that), and adding them just makes for more work and more problems. And, when you have a bug caused by race-condition/deadlock, you're going to have a helluva time debugging it. I just wanted to make sure you were aware of this, and that you truly need to use threads. [/quote] Yeah, I could probably do without threads but I want to have them. If I use the message-passing style of thread-safety, then I won't have to worry about those since they will be accessing their own local set of variables. I don't mind doing the extra work/research to implement multiple-threads. Once I do get a working system of thread-safety, I will be able to use it in most of my applications. I also know when it is okay/not okay to use EnterCriticalSection and other such alternatives to thread-safety.
  5. C++ Thread safety

    I see what you guys mean now. All the other synchronization methods suck I am trying to imagine how this will fit in my game and a few issues come to mind. I draw my own textboxes, so I need to have a copy of the string there, I also need a copy in the input thread because when a button is clicked, I need that data from the textbox. I also am wondering about characters. I will need a copy of the characters to be drawn, but I will also need a copy in the network thread when walk packets and such are sent. This seems all a bit messy.
  6. C++ Thread safety

    Yeah, I read the article and I the idea intrigued me, but I would still like to look at all possible options. The method seems like a 'work-around' to synchronizing data. I am not sure what the efficiency of critical sections are compared to the message-queue idea. If using critical sections will cause a major overhead, then yes, I will most likely use your idea because it is the next best thing. I don't think overloading the queue with update messages is the idea, plus it will create (number of threads) * local data bytes while my method just creates 1 * local data bytes. I have 7 threads, which will create 6x more memory than I need. Plus, I will end up overloading the queue with update messages when I could just use a critical section, and at the tops it will block the thread for 1ms. I will probably put a timeout value on the critical section so it won't block the queue more than a few seconds. As long as I don't enter the critical section until I absolutely need to write/read a value, then the read/write will seem almost instantaneous. I am going to do some tests with windows critical sections to see their performance. It seems the simplest since I get to decide when to lock and unlock it. I have seen performance problems with shared_ptr if not used correctly, and I don't want to take that chance. Atomic's have caused me problems in the past, and I would prefer not having to deal with them. If anyone has reasons not to use critical sections, then I would appreciate information on why. Picking how to make a program thread-safe is a really tough decision in life
  7. C++ Thread safety

    Yeah, I see how that would work well. How much overhead does smart pointers or critical sections have. It seems like a lot of trouble to have locak copies of all the data if the overhead isn't going to be noticeable. Theoretically thinking about it, the time to lock, exit value, and unlock wouldn't be noticeable. The issue is how much memory critical sections take upup
  8. C++ Thread safety

    If I were to use smart pointers to ensure thread safety, then what would I do for regular variables? Would I just turn that into a variable and deference it when I needed to change it? If I were to use smart pointers and I wrap a smart pointer around a class and each thread accesses that smart pointer at the same time, is the data inside the class thread safe? If all the threads call a function from the smart pointer and that function accesses data inside the class, is it thread-safe? I still don't have legitimate reasons not to use atomics. They seem like a good idea, but I don't know how efficient they are. Reading about atomics, it seems that it all is based upon your CPU.
  9. C++ Thread safety

    I'm not sure if it would even be beneficial to have multiple threads if I use a queue system to get and set data. I could make a copy of it, but still the data needs to be synchronized between all threads to be accurate. The whole Form class is going to be accessed by each thread and the data inside of it. If I make a copy of all of that, that's about 8x the Form class then I need and want I just want one instance of the Form class, and I want it to be able to be safely accessed by all of the threads. I have seen threads about shared_ptr being slow, and I could believe that. I think they overdid it with the shared_ptr. EnterCriticalSection is what I'm leaning towards, but I'm not sure if I should have one critical section for the whole form, or for the variables inside the critical section. Also, what does Linux/Unix offer for thread safety? I did plan on making this project for other OS systems, and if they don't offer something just as fast and simple, then I would be right back to this question.
  10. C++ Thread safety

    Haha, I wish I didn't have to share data between the threads, but I do I think I understand what you're saying, and that might just work out. I would still have to synchronize the data, but what you're saying could work better. Well, to think of it, I am using OpenGL to render. I actually have to set the context in the thread to the OpenGL one at initialization. It would be somewhat wasteful to set the context of each thread in the pool.
  11. Hello everyone, I am planning on making a game with C++ and I am wanting it to be multi-threaded. The biggest issue with having multiple threads is making it thread-safe. I know of the many ways to make it safe, but I want to know, what will be the BEST and FASTEST for me. My primary question is what's the fastest, but if you want to list off the pros/cons of each one, then hey, I don't mind learning more Basically, I am going to have 4 threads for loading content, one thread for input/output, one thread for rendering, and one thread for networking. I am going to have a Form class to represent the current Form/Screen. This Form class will be the basis of where I need to start worrying about thread-safety. The Form class will have a HandlePacket,Draw, and HandleInput functions that will each be called from different threads. The form will have variables in there that will be accessed from each thread. I do know that mutexes are slower than windows EnterCriticalSection/LeaveCriticalSection since the critical section is user mode and mutexes are performed at a kernel mode. But, I am not sure if boost's smart pointers are faster than critical sections. I did try out atomics for a bit, but it actually deadlocked a program for no reason at one point. I also heard of having TLS, which could possibly work. If I were to use smart pointers, would I make the form a smart pointer, or just the data inside of it? If I were to use TLS, the data wont be synchronized per thread, correct? If I were to use EnterCriticalSection/LeaveCriticalSection, would I have a CriticalSection variable for each variable inside the form, or just one for the form? I am going for a balance between memory and performance effeciency. So, I don't want the option that takes a ton of memory but is fast, and I don't want the option that takes no memory, but is slow. A good balance would be ideal for me. I would greatly appreciate a pros/cons list of my options because going from website to website, someone seems to say something different. It would help set me straight on what works and what doesn't. Thank you in advance.
  12. The topic title about says it all, does SharpDX offer a D3DFVF_TEXCOORDSIZEN enum? If not, I'm sure I could just calculate the numbers myself and even make an enum myself, just wanting to be proper and use it if they had it.
  13. Oh okay, that makes sense, then no I do not have that. I will have to learn how to do that. Is there a limit of how big the 3D texture can be? The width/height maximum texture size will be the same as a 2D texture, but what about depth-wise?
  14. [quote name='streamer' timestamp='1341944131' post='4957698'] [quote name='addy914' timestamp='1341939612' post='4957660'] Thanks d k h, that story is really comforting to know. It tells me that spritesheets are the way to go for sure. I am wanting to support older graphic cards, so I am trying to pick a relatively low texture size that a lot of graphic cards will support. From what mhagain says, I should be safe with 1024x1024, which sounds good. Even if I were to use 4096x4096 or whatever texture size, I am wanting to answer the question "What if I exceed that size with my textures?" I am trying to think on a bigger scale(which in the game I'm making, I will certainly exceed 1024x1024 a few times). I could make another textures to hold this data but whenever I am in the rendering layer, I would most likely end up switching textures from the first page to the second page. As I slowly add on more and more "pages" of textures, the more I have to switch textures between them. Any ideas? [/quote] As I stated before 3D textures are way to go, if you are concerned about switching textures. If you feel any problem with 3D textures (yes they may not work on really old hardware) then your only way to go is to determine maximum texture size available on computer through caps, then dynamically create bigger texture sheet. Say you have 4 textures with 1024x1024 size and maximum available texture size on computer is 4096x4096, then you during loading process putt all 4 textures on one bigger. Of course you will need to have special class for handling UV of dynamically created textures but that is another story. But as mhagain stated probably you will not have too much problems with texture switching, biggest bottleneck you will probably have is a number of draw calls. Just try to make 4000 BeginSprite/DrawSprite/EndSprite calls then make same with 1 BeginSprite, 4000 DrawSprite and 1 EndSprite call,l and you will understand the problem. [/quote] I believe I am already using 3D textures? I am doing this in C# using SharpDX, and I only use the Direct3D9 class, so I assume it's a 3D texture. I also have a function to call BeginScene and one to call EndScene. So I call BeginScene, draw everything that is needed on the screen, and then call EndScene & Present to display it. The number of draw calls is inevitable because it doesn't matter if I use a spritesheet or not, I will have to call the draw function the same amount of times.(approximately, not enough to notice) I think I will make another test program and get some data seeing how slow SetTexture is. "I could make another textures to hold this data but whenever I am in the rendering layer, I would most likely end up switching textures from the first page to the second page. As I slowly add on more and more "pages" of textures, the more I have to switch textures between them." I am still not sure what to do about this issue. I actually didn't think of making a bunch of 1024x1024 spritesheets, and then combining them to the graphic cards max texture size. That will make it more efficient. I can also spit out an error message if they don't have at least a 1024x1024 max texture size.
  15. Thanks d k h, that story is really comforting to know. It tells me that spritesheets are the way to go for sure. I am wanting to support older graphic cards, so I am trying to pick a relatively low texture size that a lot of graphic cards will support. From what mhagain says, I should be safe with 1024x1024, which sounds good. Even if I were to use 4096x4096 or whatever texture size, I am wanting to answer the question "What if I exceed that size with my textures?" I am trying to think on a bigger scale(which in the game I'm making, I will certainly exceed 1024x1024 a few times). I could make another textures to hold this data but whenever I am in the rendering layer, I would most likely end up switching textures from the first page to the second page. As I slowly add on more and more "pages" of textures, the more I have to switch textures between them. Any ideas?