Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 21 Oct 2011
Offline Last Active Aug 27 2015 05:12 AM

#5221478 The Atomic Man: Are lockless data structures REALLY worth learning about?

Posted by on 05 April 2015 - 09:14 AM

I think this topic is interesting and worth knowing for game development (see Ubisoft examples later).


The good news is that -- if you'd like to learn -- there's now plenty of really good materials available.


I'd start with Herb Sutter's talks: atomic Weapons: The C++ Memory Model and Modern Hardware

Then, watch his CppCon 2014 talks, "Lock-Free Programming (or, Juggling Razor Blades)": http://herbsutter.com/2014/10/18/my-cppcon-talks-2/
* Part 1: Lazy initialization with DCL vs. call_once vs. function local statics, and lock-free mailbox algorithms
* Part 2: Lock-free linked lists, the ABA problem, and atomic smart pointers

(Note: "Example-driven talk on how to design and write lock-free algorithms and data structures using C++ atomic -- something that can look deceptively simple, but contains very deep topics. (Important note: This is not the same as my "atomic Weapons" talk; that talk was about the "what they are and why" of the C++ memory model and atomics, and did not cover how to actually use atomics to implement highly concurrent algorithms and data structures.)")

Last but definitely not least, I highly recommend following Jeff Preshing's (a Technical Architect at Ubisoft Montreal) blog: http://preshing.com/

For instance, check out his talk at CppCon 2014: "How Ubisoft Develops Games for Multicore - Before and After C++11"


Getting familiar with Boost.Lockfree shouldn't hurt, either:


Good luck!

#5206922 Some programmers actually hate OOP languages? WHAT?!

Posted by on 27 January 2015 - 09:21 AM

Problem is, I will never learn the right way to code from the wrong way if I don't share my code and no one explains it to me.

TL;DR - unless you've been telling everyone that you're the greatest software engineer who's ever lived, you should never feel like that.


. . .



To add to that:

- Egoless Programming: http://blog.codinghorror.com/egoless-programming-you-are-not-your-job/

- You Are Not Your Code: http://www.hanselman.com/blog/YouAreNotYourCode.aspx

#5180101 Aspiring Game Developer, Fluent in C++, What Do I Learn Now?

Posted by on 13 September 2014 - 02:11 PM

I'd also add Lua -- it's more minimalistic than Python and is often useful for embedding as a scripting language for your game (so that the players can extend it: modify the AI behavior, add custom scenarios, etc.). In fact, Lua would be my first choice for an embedded scripting language (not just) in a gamedev context.


It's also very easy to get started: http://www.lua.org/pil/


Here's a comparison: http://lua-users.org/wiki/LuaVersusPython (even though it's hosted on lua-users it points both the upsides and the downsides of both).


OTOH, if you already know Python, picking up Perl wouldn't necessarily have the highest priority (the use-cases of these substantially overlap).

#5132612 SFML - Can't even compile tutorial code

Posted by on 19 February 2014 - 06:55 AM

Try simply following the official tutorials: http://www.sfml-dev.org/tutorials/2.1/

#5122255 C++ templates, are they worth it?

Posted by on 08 January 2014 - 04:40 PM

These are some pretty good starting points ("old-code-can-call-new-code" is a pretty succinct description):

One other thing -- they go hand in hand with "auto" and genericity:

For instance, instead of writing:

int add(int a, int b) { return a + b; }
float add(float a, float b) { return a + b; }
double add(double a, double b) { return a + b; }

int x = add(1, 2);
float y = add(1.f, 2.f);
double z = add(1., 2.);

You can simply write:

template <typename T>
T add(T a, T b) { return a + b; }

auto x = add(1, 2);
auto y = add(1.f, 2.f);
auto z = add(1., 2.);

So they help you achieve generic, reusable code that doesn't just work for a particular type, but for a bunch of types that happen to satisfy a concept: http://en.cppreference.com/w/cpp/concept

// This concept is implicit here -- operator "+" has to exist. You can make it explicit with type-traits, static_assert, and enable_if.


This is useful -- say, instead of "add" taking two numbers, think of "will_first_monster_win" taking two monsters:

template <typename FirstMonsterType, typename SecondMonsterType>
bool will_first_monster_win(const FirstMonsterType & first_monster, const SecondMonsterType & second_monster)
  return strength(first_monster) >= strength(second_monster); // super-fancy combat algorithm!

Now, if you add new monster types to your game, your "will_first_monster_win" function will keep working unmodified -- as long as the relevant (new) "strength" function exists (let's call this particular existence requirement a "has-strength" concept -- in other words, FirstMonsterType & SecondMonsterType in the "will_first_monster_win" function will successfully match any types that satisfy the "has-strength" concept). In other words, you can extend your code (and add new code) without modifying the already written ("old") code: https://en.wikipedia.org/wiki/Open/closed_principle

// Note: the linked article happens to use inheritance/inclusion-run-time-polymorphism (typical OOP technique) to illustrate this; in many ways, however, templates/compile-time-polymorphism (typical Generic Programming) as in the "will_first_monster_win" example will work just as well if not better.


Without templates, you'd have to know the types of your monsters in advance / right at the moment when you're implementing "will_first_monster_win" -- and then rewrite it / provide overloads / etc. each time you add new monster type. Or just settle for a boring game with fixed monster types :-(


With templates you can save quite some time, speed up your experiments, and keep adding increasingly cruel monsters, so you can provide more fun for the players :-)

#5120180 When to use polymorphism

Posted by on 30 December 2013 - 05:40 PM

To start with, C++ offers several distinct forms of polymorphism, each one with different use cases in mind (and different trade-offs).

To be able to make an informed choice, it's a good idea to become familiar with them all:



You'll learn some of the trade-offs the hard way, after discovering that working on your game (or other program) becomes harder over time, when adding more features forces you to go back to the old code that wasn't written with them in mind, etc. And that's OK, this is how you learn and improve -- as long as you Refactor Mercilessly!


It's especially worth noting that run-time polymorphism is very much possible (and arguably cleaner!) without inheritance -- I strongly recommend watching this:


#5120177 gui/game librarys FOR C++

Posted by on 30 December 2013 - 05:33 PM

I'd also recommend SFML: http://www.sfml-dev.org/

Don't forget the docs: http://www.sfml-dev.org/resources.php

#5095447 Does C++ <random> lib require seeding?

Posted by on 20 September 2013 - 06:45 AM

Because reproducibility is desirable, while non-reproducibility is undesirable.

// See, for instance, http://openmd.org/?p=257

Think how hard debugging would be if you couldn't guarantee the same execution path of your program.


Besides, even if you were fine with non-reproducibility, seeding with time functions is often a bad idea -- at least, you'd need a high resolution timer.

As an alternative, you can do the following:

std::random_device rdev{}; // ASSUMPTION: your implementation / target platform actually guarantees this is random
std::default_random_engine e{rdev()}; // seed with the aforementioned source of randomness


For more, read this:


#5095438 Effective C++ (book)

Posted by on 20 September 2013 - 06:26 AM

See also previous thread:


#5087324 Generic Datatypes --Are Templates the Way to Go?

Posted by on 19 August 2013 - 10:23 AM

The reason I wanted my own type of lists is mainly due to std::list iterators. Having to declare an iterator every time I want to get to a specific element is just plain annoying. It takes like 3 or 4 lines of code to get to that specific element I already know I want. I've thought about vectors since I'd be able to refer to my elements by index, but then everything's aligned in memory. Although memory alignment has its benefits, adding elements to a vector could cause the entire array to relocate in memory to ensure everything is memory-aligned. This can be slow when adding data --especially larger elements.


I would still consider using std::vector, see: Bjarne Stroustrup: Why you should avoid Linked Lists.

The cache benefits of std::vector using contiguous memory are so massive that they may in practice outweigh the benefits provided by the lists, EVEN when inserting/removing elements in the middle. It's a trade-off; what's your relative access-to-modification ratio? It's worth checking the performance with profiler (ideally, avoid synthetic benchmarks, and test with your actual gameplay, e.g., using automated replay feature (assuming you have that in your engine)).


See “Software Development for Infrastructure” for more details and the graph mentioned in the video.

We should prefer sequential access of compact structures, not thoughtlessly use linked structures, and avoid general memory allocators that scatter logically related data. We must measure to avoid being blind-sided by unexpected phenomena. Our systems are too complex for us to guess about efficiency and use patterns.





#5086073 EventBus - Possible with C++ templates?

Posted by on 15 August 2013 - 05:23 AM

the event bus calls handleEvent using the engine pointer (the logfile says it is the engine) ... but it seems that the handleEvent of EventHandler is called, not Engine.

Why is that?


Doesn't virtual mean that it shouldn't matter that the EventBus is working with an EventHandler pointer?


Only if you store & call it via a pointer (or its variants, like std::unique_ptr) or a reference (or its variants, like std::reference_wrapper).

Otherwise, object slicing occurs.


Just like here, where you store by value:

std::list< EventHandler<E> > m_handlerList; // oops


and here, where you call your stored-by-value (and sliced) handler

for (typename std::list< EventHandler >::iterator it = m_handlerList.begin(); m_handlerList.end() != it ; ++it) // oops
EventHandler handler = *it; // oops

*pMessage << "Informing handler nr. " << i << ": " << handler.getName().c_str();
m_pLogger->log(pMessage, Logger::LOGLEVEL_DEBUG);
handler.handleEvent(pEvent); // this is sliced

#5085609 EventBus - Possible with C++ templates?

Posted by on 13 August 2013 - 01:30 PM

(0) Would love to answer all your questions ... but I can't think straight right now.

(1) Can't wrap my head around static polymorphism and runtime polymorphism.


Basically what I want to do is avoid adding all modules to all modules. I want an event bus to couple them more loosely.


(2) I still don't see how a function can be more powerful than a class.


(0) I guess trying out a couple of alternative, throwaway but concrete (compilable) solutions might be your best course of action, then.


(1) Go through this and try out the examples, that should do it: http://accu.org/index.php/journals/538


Note that static forms of polymorphism (both parametric/templates and overloading) are somewhat more powerful in C++ than dynamic polymorphism (in form of inclusion polymorphism/inheritance), since they support multiple dispatch out-of-the-box (so there's no need for things like the visitor pattern in Java if you're fine with the compile-time world), see: http://www.codeproject.com/Articles/635264/Open-Multi-Methods-for-Cplusplus11-Part-1

To see how this comes up in game development, consider the asteroids-spaceships collisions example:


// Note that if you need dynamic/run-time polymorphism, you will also need to use something like the visitor pattern (or a library-based solution), even in C++.


(2) Things like std::function support type-erasure and directly support catamorphisms (again, completely eliminate the need for design patterns like the visitor pattern), so a lot of the things you'd normally need a lot of OOP boilerplate for (to implement the design patterns) are simply supported out of the box (no manually written boilerplate code) if you write in FP style:




In particular, in OOP style you often have to waste your time coding some brittle/rigid boilerplate requiring inheritance, while in FP style with std::function you can completely decouple many of your components. Here's another example in the gamedev context: http://probablydance.com/2012/12/16/the-importance-of-stdfunction/


Consider the traditional (OOP/inheritance solution):

But you’ve got that inheritance in there, and that doesn’t scale. You will probably want to add a render loop and maybe a separate update loop for the editor. Once you’ve got that many base classes it makes sense to combine them into one. And now you’ve just started on the way of having a big base class that gets used everywhere. Soon enough adding something different to the update loop involves a whole lot of unnecessary work.


And compare with the FP one:

This has no inheritance. Meaning I can add anything to the update loop now. If I create a new object that is unrelated to anything I had before and is managed completely differently, I can still add it just as easily as anything else. And I can use the same idea for a render loop or for implementing an observer pattern. It makes everything immensely easier.

Perhaps this is exactly what you're looking for?


Just as with anything in programming, there ain't no such thing as a free lunch, so each solution has upsides and downsides -- it's your wonderful job as a designer to compare and contrast each and chose the least-imperfect one for the task at hand :-)


In particular, both std::function and OOP/inheritance will have a run-time cost related to type-erasure/virtual function call; in contrast, if it's possible for you to know the types at compile-time and you can design & code a GP solution with templates, you won't suffer any overhead of this type (although may have icache trade-offs to consider, etc.).

#5085228 Mathbook for dummies, any recomendation?

Posted by on 12 August 2013 - 10:34 AM

This reminded me of EWD's comments:


But things have changed. These days it is quite common that students don't even know the name of the person who is lecturing to them, let alone that they feel proud to be his student! And it is equally common that faculty talk about students, in particular undergraduates, as if they were animals from another planet. Students are no longer seen as part of the solution, but as part of the problem, and textbooks and lecturing techniques have become so condescending that, if I were a student, I would take offence. I don't think that I could stand a lecturer that assumes that my attention span is no more than 7 minutes or who feels obliged to feed me a cartoon every 5 foils, and subjects me to multiple-choice tests because I am supposed to be functionally illiterate. I invite you to read carefully the catalogues of publishers of mathematical textbooks: obviously, colour math is better than B&W math, most books are recommended for being intuitive instead of formal, for being chatty instead of crisp, for being vague and sloppy instead of rigorous. It is clearly an article of the New Faith that teaching the real thing would be counter-productive: just as our students are supposed to live on junk food, they are supposed to thrive on junk science.


The loss of mutual respect has affected more than just the educational process, it has corroded publication as well. In 1975 I received a letter that objected to the style in which I had written an article for the Communications of the ACM (= Association for Computing Machinery). The complaint was that, by separating my concerns more strictly than usual, I had addressed my intended audience in a style they were not used to. The writer continued with the well-known quotation from P.T.Barnum that "No one ever got broke by underestimating the intelligence of the American people." and urged me to bear that in mind whenever I wrote for the programming community. So, 25 years ago, the rot had already set in; at the end of the century it would lead to an endless series of fat, yellow books titled "Such and such for dummies". Allow me to quote in contrast from "The elements of Style" by Strunk and White, because it reflects a much more inspiring spirit; "No one can write decently who is distrustful of the reader's intelligence, or whose attitude is patronizing.".

#5085212 Web Services Framework

Posted by on 12 August 2013 - 09:46 AM

Add one more to the list: http://code.google.com/p/staff/


gSOAP looks more like C than C++: http://www.cs.fsu.edu/~engelen/calc.html


In comparison: http://code.google.com/p/staff/wiki/BriefExamples#Simple_service_and_client:_Calculator

// Although the use of deprecated std::auto_ptr is also worrying, nowadays one should use std::unique_ptr instead.


There's also Qt SOAP: http://doc.qt.digia.com/solutions/4/qtsoap/


See also http://stackoverflow.com/questions/1866080/is-there-any-standard-to-consume-a-webservice-inside-of-native-c

#5084815 sorting std::vector instead of array

Posted by on 10 August 2013 - 06:31 PM

BTW, if you're using C++11, it's a good idea to use std::begin and std::end:




These will work both with the containers and C-style (fixed) arrays -- useful for situations just like this, when you're switching between the two.

// Although some tweaking is needed for the C-style dynamic arrays: http://stackoverflow.com/questions/15904896/range-based-for-loop-on-a-dynamic-array