Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

Learning from code - larger TBB example

Nav
New Contributor I
1,725 Views
During my fledgling days of learning GW-BASIC, it was source codes of games like Nibbles written in GW-BASIC that helped me build my skills as a programmer and induced a love for programming in me. Making games on my own resulted in badly structured logic, until I saw those source codes and I was like "Aha! so that's how they do it!!". T'was ice-cream for my mind as a child :)
Programmers learn from existing code.

There are plenty of tiny pieces of TBB code lying around in the internet. But is there a website or do any one of you have source code where either a small (complete) application is programmed in TBB or a game like PacMan is programmed in TBB?

Seeing such a program is important to me as a programmer, because it helps in better visualizing, planning and understanding how I can make use of TBB.

I've seen this site, but I get a server error everytime I try to download. The Intel website has TBB code for Visual C++. I don't have Visual C++, and need something that I can compile with GCC on Linux.

Anyone who could help?
0 Kudos
1 Solution
IDZ_A_Intel
Employee
1,725 Views
Smoke is constituted by several subsytems: Geometry, Physics, Rendering, AI, Procedural Fire, Procedural Trees, Audio, etc. Each subsytem consists of a bunch of objects. Objects can issue notifications about their state change, and can subscribe for notifications from other objects. These relations are established at the game initialization stage.

The main loop of the game looks like follows:

Start program
Read config, create subsystems and their objects
Subscribe objects to notifications from other objects and sybsytems
initialize TBB // common thread pool is created here
while ! end of game
ProcessFrame
DistributeChangeNotifications
end of while
End program

ProcesFrame spawns a task for each subsystem. Some of these tasks (most computentionally intensive ones) use nested parallelism (mainly in the form of tbb::parallel_for) to achive good load balancing.

Rendering task renders the state of the objects calculated at the previous iteration. At the same time most of the other subsytems calculate the new state of the objects concurerntly.

Change notifications are accumulated in the thread local manner, and after ProcessFrame is finished are distributed concurrently (using tbb::parallel_for again) to subscribers.

Achieving good scalability also requires careful containers structure design to minimaize memory allocations/deallocations and synchronization.

You may also have a look at the "Parallelization of SMOKE Gaming Demo via Intel Threading Building Blocks" whitepaper.

View solution in original post

0 Kudos
9 Replies
Anton_Pegushin
New Contributor II
1,725 Views
Hi,
somewhere on this forum I saw Dmitry Vyukov posting a link to Google's Code Search with "task_scheduler_init" as a search string and Code Search reported about 280 pieces of code that used TBB and I remembered that some of those did look reasonable and informative. So maybe Code Searchcan help.

Another thing I'd definitely take a look at is examples distributed as a part of TBB package. These are there not only to demonstrate TBB functionality, but also to teach which algorithm should be used in each case and how to use them to ensure optimal scalability and performance. Examples come not only with VS solution files, but with makefiles as well, so you can easily build those on Linux and give them a try.
0 Kudos
Nav
New Contributor I
1,725 Views
You're showing me how fish, instead of giving me the fish! Your reply about code search has been very very helpful!

Yes, I've also been through the examples that came with TBB, but was looking for something broader. The examples demonstrate specific functionalities. Was looking for code which would demonstrate how to piece these functionalities together. While a game program would be the best to help in visualising the problem, I guess it's just a matter of practice that aids in visualization.
Will be trying out code on my own, and the request for help is still open... :)
0 Kudos
Andrey_Marochko
New Contributor III
1,725 Views
Have a look at the "Smoke - Game Technology Demo" on ISN. It should use TBB under the hood (wrapped into scheduler interface of their own). In particular procedural fire uses deeply (triply to be more precise) nested parallelism there.

0 Kudos
Nav
New Contributor I
1,725 Views
Thanks Andrey. Had a look at the video, and I know that I do not have the resources to actually try the example, but I was intrigued at how TBB has been used in the context.

From what I could understand, the AI, Rendering, Audio etc are independent modules, and TBB is like an external layer which supplies threads to these modules. Is that how it works? Coz if it is, then (as an example) you wouldn't need to go into any of the AI code and parallelise it right?

So would the logic be like:
Start program
while ! end of game
spawn a task with x threads for AI
spawn a task with x threads for Rendering
spawn a task with x threads for Audio
.
.
.
end of while
end program


or does the logic go like:

Start program
spawn x threads
while ! end of game
do the AI where more threads/tasks are spawned internally
do the Rendering where more threads/tasks are spawned internally
.
.
.

end of while
end program

Forgive me for the immaturity of the logic. I'm just not able to get how TBB is used in a larger context.
0 Kudos
RafSchietekat
Valued Contributor III
1,725 Views
"a task with x threads"
TBB is all about having many finite tasks executed by a global worker pool of threads, so that couldn't possibly be it.
0 Kudos
IDZ_A_Intel
Employee
1,726 Views
Smoke is constituted by several subsytems: Geometry, Physics, Rendering, AI, Procedural Fire, Procedural Trees, Audio, etc. Each subsytem consists of a bunch of objects. Objects can issue notifications about their state change, and can subscribe for notifications from other objects. These relations are established at the game initialization stage.

The main loop of the game looks like follows:

Start program
Read config, create subsystems and their objects
Subscribe objects to notifications from other objects and sybsytems
initialize TBB // common thread pool is created here
while ! end of game
ProcessFrame
DistributeChangeNotifications
end of while
End program

ProcesFrame spawns a task for each subsystem. Some of these tasks (most computentionally intensive ones) use nested parallelism (mainly in the form of tbb::parallel_for) to achive good load balancing.

Rendering task renders the state of the objects calculated at the previous iteration. At the same time most of the other subsytems calculate the new state of the objects concurerntly.

Change notifications are accumulated in the thread local manner, and after ProcessFrame is finished are distributed concurrently (using tbb::parallel_for again) to subscribers.

Achieving good scalability also requires careful containers structure design to minimaize memory allocations/deallocations and synchronization.

You may also have a look at the "Parallelization of SMOKE Gaming Demo via Intel Threading Building Blocks" whitepaper.

0 Kudos
Nav
New Contributor I
1,725 Views
:) I guess it's time for me to say "Aha! So that's how you do it!" :)
Your reply solves my doubts.
Thank you so much!!! :)
0 Kudos
Nav
New Contributor I
1,725 Views
Thank you Dmitriy :)
0 Kudos
Reply