SlideShare a Scribd company logo
1 of 67
Download to read offline
The Next Mainstream
Programming Language:
A Game Developer’s Perspective
The Next Mainstream
The Next Mainstream
Programming Language:
Programming Language:
A Game Developer
A Game Developer’
’s Perspective
s Perspective
Tim Sweeney
Tim Sweeney
Epic Games
Epic Games
Outline
ƒ Game Development
– Typical Process
ƒ What’s in a game?
– Game Simulation
– Numeric Computation
– Shading
ƒ Where are today’s languages failing?
– Concurrency
– Reliability
Game Development
Game Development: Gears of War
ƒ Resources
– ~10 programmers
– ~20 artists
– ~24 month development cycle
– ~$10M budget
ƒ Software Dependencies
– 1 middleware game engine
– ~20 middleware libraries
– OS graphics APIs, sound, input, etc
Software Dependencies
Gears of War
Gameplay Code
~250,000 lines C++, script code
Gears of War
Gameplay Code
~250,000 lines C++, script code
Unreal Engine 3
Middleware Game Engine
~250,000 lines C++ code
Unreal Engine 3
Middleware Game Engine
~250,000 lines C++ code
DirectX
Graphics
DirectX
Graphics
OpenAL
Audio
OpenAL
Audio
Ogg
Vorbis
Music
Codec
Ogg
Vorbis
Music
Codec
Speex
Speech
Codec
Speex
Speech
Codec
wx
Widgets
Window
Library
wx
Widgets
Window
Library
ZLib
Data
Compr-
ession
ZLib
Data
Compr-
ession
…
Game Development: Platforms
ƒ The typical Unreal Engine 3 game will
ship on:
– Xbox 360
– PlayStation 3
– Windows
ƒ Some will also ship on:
– Linux
– MacOS
What’s in a game?
The obvious:
ƒ Rendering
ƒ Pixel shading
ƒ Physics simulation, collision detection
ƒ Game world simulation
ƒ Artificial intelligence, path finding
But it’s not just fun and games:
ƒ Data persistence with versioning, streaming
ƒ Distributed Computing (multiplayer game simulation)
ƒ Visual content authoring tools
ƒ Scripting and compiler technology
ƒ User interfaces
Three Kinds of Code
ƒ Gameplay Simulation
ƒ Numeric Computation
ƒ Shading
Gameplay Simulation
Gameplay Simulation
ƒ Models the state of the game world as
interacting objects evolve over time
ƒ High-level, object-oriented code
ƒ Written in C++ or scripting language
ƒ Imperative programming style
ƒ Usually garbage-collected
Gameplay Simulation – The Numbers
ƒ 30-60 updates (frames) per second
ƒ ~1000 distinct gameplay classes
– Contain imperative state
– Contain member functions
– Highly dynamic
ƒ ~10,000 active gameplay objects
ƒ Each time a gameplay object is updated, it
typically touches 5-10 other objects
Numeric Computation
ƒ Algorithms:
– Scene graph traversal
– Physics simulation
– Collision Detection
– Path Finding
– Sound Propagation
ƒ Low-level, high-performance code
ƒ Written in C++ with SIMD intrinsics
ƒ Essentially functional
– Transforms a small input data set to a small output data
set, making use of large constant data structures.
Shading
Shading
ƒ Generates pixel and vertex attributes
ƒ Written in HLSL/CG shading language
ƒ Runs on the GPU
ƒ Inherently data-parallel
– Control flow is statically known
– “Embarassingly Parallel”
– Current GPU’s are 16-wide to 48-wide!
Shading in HLSL
Shading – The Numbers
ƒ Game runs at 30 FPS @ 1280x720p
ƒ ~5,000 visible objects
ƒ ~10M pixels rendered per frame
– Per-pixel lighting and shadowing requires multiple
rendering passes per object and per-light
ƒ Typical pixel shader is ~100 instructions long
ƒ Shader FPU’s are 4-wide SIMD
ƒ ~500 GFLOPS compute power
Three Kinds of Code
FPU Usage
Lines of Code
CPU Budget
Languages
500 GFLOPS
5 GFLOPS
0.5 GFLOPS
10,000
250,000
250,000
n/a
90%
10%
CG, HLSL
C++
C++, Scripting
Shading
Numeric
Computation
Game
Simulation
What are the hard problems?
ƒ Performance
– When updating 10,000 objects at 60 FPS, everything is
performance-sensitive
ƒ Modularity
– Very important with ~10-20 middleware libraries per game
ƒ Reliability
– Error-prone language / type system leads to wasted effort
finding trivial bugs
– Significantly impacts productivity
ƒ Concurrency
– Hardware supports 6-8 threads
– C++ is ill-equipped for concurrency
Performance
ƒ When updating 10,000 objects at 60 FPS,
everything is performance-sensitive
ƒ But:
– Productivity is just as important
– Will gladly sacrifice 10% of our performance
for 10% higher productivity
– We never use assembly language
ƒ There is not a simple set of “hotspots” to
optimize!
That’s all!
Unreal’s game framework
package UnrealEngine;
class Actor
{
int Health;
void TakeDamage(int Amount)
{
Health = Health – Amount;
if (Health<0)
Die();
}
}
class Player extends Actor
{
string PlayerName;
socket NetworkConnection;
}
Gameplay
module
Base class of
gameplay
objects
Members
Game class hierarchy
Actor
Player
Enemy
InventoryItem
Weapon
Actor
Player
Enemy
Dragon
Troll
InventoryItem
Weapon
Sword
Crossbow
Generic Game Framework
Game-Specific Framework Extension
Software Frameworks
ƒ The Problem:
Users of a framework
need to extend the functionality
of the framework’s base classes!
ƒ The workarounds:
– Modify the source
…and modify it again with each new version
– Add references to payload classes, and
dynamically cast them at runtime to the
appropriate types.
Software Frameworks
ƒ The Problem:
Users of a framework
want to extend the functionality
of the framework’s base classes!
ƒ The workarounds:
– Modify the source
…and modify it again with each new version
– Add references to payload classes, and
dynamically cast them at runtime to the
appropriate types.
– These are all error-prone:
Can the compiler help us here?
What we would like to write…
package Engine;
class Actor
{
int Health;
…
}
class Player extends Actor
{
…
}
class Inventory extends Actor
{
…
}
Base Framework
Package GearsOfWar extends Engine;
class Actor extends Engine.Actor
{
// Here we can add new members
// to the base class.
…
}
class Player extends Engine.Player
{
// Thus virtually inherits from
// GearsOfWar.Actor
…
}
class Gun extends GearsOfWar.Inventory
{
…
}
Extended Framework
The basic goal:
To extend an entire software framework’s class
hierarchy in parallel, in an open-world system.
Or:
If the compiler doesn’t beep,
my program should work
Dynamic Failure in Mainstream Languages
Vertex[] Transform (Vertex[] Vertices, int[] Indices, Matrix m)
{
Vertex[] Result = new Vertex[Indices.length];
for(int i=0; i<Indices.length; i++)
Result[i] = Transform(m,Vertices[Indices[i]]);
return Result;
};
Example (C#):
Given a vertex array and an index array, we
read and transform the indexed vertices into
a new array.
What can possibly go wrong?
Dynamic Failure in Mainstream Languages
Vertex[] Transform (Vertex[] Vertices, int[] Indices, Matrix m)
{
Vertex[] Result = new Vertex[Indices.length];
for(int i=0; i<Indices.length; i++)
Result[i] = Transform(m,Vertices[Indices[i]]);
return Result;
};
May be NULL May be NULL
May contain indices
outside of the range of
the Vertex array
May be NULL
Array access
might be out
of bounds
Will the compiler
realize this can’t fail?
Could dereference
a null pointer
Our code is littered with runtime failure cases,
Yet the compiler remains silent!
Dynamic Failure in Mainstream Languages
Solved problems:
ƒ Random memory overwrites
ƒ Memory leaks
Solveable:
ƒ Accessing arrays out-of-bounds
ƒ Dereferencing null pointers
ƒ Integer overflow
ƒ Accessing uninitialized variables
50% of the bugs in Unreal can be traced to these problems!
What we would like to write…
Transform{n:nat}(Vertices:[n]Vertex, Indices:[]nat<n, m:Matrix):[]Vertex=
for each(i in Indices)
Transform(m,Vertices[i])
Universally quantify over
all natural numbers
An array of exactly known size
An index buffer containing natural numbers less than n
Haskell-style array
comprehension
The only possible failure mode:
divergence, if the call to
Transform diverges.
How might this work?
ƒ Dependent types
ƒ Dependent functions
ƒ Universal quantification
int
nat
nat<n
Sum{n:nat}(xs:[n]int)=..
a=Sum([7,8,9])
Sum(n:nat,xs:[n]int)=..
a=Sum(3,[7,8,9])
The Integers
The Natural Numbers
The Natural Numbers less than n,
where n may be a variable!
Explicit type/value dependency
between function parameters
How might this work?
ƒ Separating the “pointer to t” concept
from the “optional value of t” concept
ƒ Comprehensions (a la Haskell),
for safely traversing and generating
collections
xp:^int
xo:?int
xpo:?^int
A pointer to an integer
An optional integer
An optional pointer to an integer!
Successors(xs:[]int):[]int=
foreach(x in xs)
x+1
How might this work?
A guarded casting mechanism for cases
where need a safe “escape”:
All potential failure must be explicitly
handled, but we lose no expressiveness.
GetElement(as:[]string, i:int):string=
if(n:nat<as.length=i)
as[n]
else
“Index Out of Bounds”
Here, we cast i to
type of natural numbers bounded by
the length of as,
and bind the result to n
We can only access i
within this context
If the cast fails, we
execute the else-branch
Analysis of the Unreal code
ƒ Usage of integer variables in Unreal:
– 90% of integer variables in Unreal exist to index into arrays
• 80% could be dependently-typed explicitly,
guaranteeing safe array access without casting.
• 10% would require casts upon array access.
– The other 10% are used for:
• Computing summary statistics
• Encoding bit flags
• Various forms of low-level hackery
ƒ “For” loops in Unreal:
– 40% are functional comprehensions
– 50% are functional folds
Accessing uninitialized variables
ƒ Can we make this work?
This is a frequent bug. Data structures are often rearranged,
changing the initialization order.
ƒ Lessons from Haskell:
– Lazy evaluation enables correct out-of-order evaluation
– Accessing circularly entailed values causes thunk reentry (divergence),
rather than just returning the wrong value
ƒ Lesson from Id90: Lenient evaluation is sufficient to guarantee this
class MyClass
{
const int a=c+1;
const int b=7;
const int c=b+1;
}
MyClass myvalue = new C; // What is myvalue.a?
Dynamic Failure: Conclusion
Reasonable type-system extensions could statically eliminate all:
ƒ Out-of-bounds array access
ƒ Null pointer dereference
ƒ Integer overflow
ƒ Accessing of uninitialized variables
See Haskell for excellent implementation of:
– Comprehensions
– Option types via Maybe
– Non-NULL references via IORef, STRef
– Out-of-order initialization
Integer overflow
The Natural Numbers
Factoid: C# exposes more than 10 integer-like data
types, none of which are those defined by
(Pythagoras, 500BC).
In the future, can we get integers right?
data Nat = Zero | Succ Nat
Can we get integers right?
Neat Trick:
ƒ In a machine word (size 2n), encode an integer ±2n-1 or a pointer to a
variable-precision integer
ƒ Thus “small” integers carry no storage cost
ƒ Additional access cost is ~5 CPU instructions
But:
ƒ A natural number bounded so as to index into an active array is
guaranteed to fit within the machine word size (the array is the proof
of this!) and thus requires no special encoding.
ƒ Since ~80% of integers can dependently-typed to access into an
array, the amortized cost is ~1 CPU instruction per integer operation.
This could be a viable
tradeoff
Concurrency
The C++/Java/C# Model:
“Shared State Concurrency”
ƒ The Idea:
– Any thread can modify any state at any
time.
– All synchronization is explicit, manual.
– No compile-time verification of
correctness properties:
• Deadlock-free
• Race-free
The C++/Java/C# Model:
“Shared State Concurrency”
ƒ This is hard!
ƒ How we cope in Unreal Engine 3:
– 1 main thread responsible for doing all work we
can’t hope to safely multithread
– 1 heavyweight rendering thread
– A pool of 4-6 helper threads
• Dynamically allocate them to simple tasks.
– “Program Very Carefully!”
ƒ Huge productivity burden
ƒ Scales poorly to thread counts
There must be a better way!
Three Kinds of Code: Revisited
ƒ Gameplay Simulation
– Gratuitous use of mutable state
– 10,000’s of objects must be updated
– Typical object update touches 5-10 other objects
ƒ Numeric Computation
– Computations are purely functional
– But they use state locally during computations
ƒ Shading
– Already implicitly data parallel
Concurrency in Shading
ƒ Look at the solution of CG/HLSL:
– New programming language aimed at
“Embarassingly Parallel” shader programming
– Its constructs map naturally to a data-parallel
implementation
– Static control flow (conditionals supported via
masking)
Concurrency in Shading
Conclusion: The problem of data-parallel concurrency is effectively solved(!)
“Proof”: Xbox 360 games are running with 48-wide data shader
programs utilizing half a Teraflop of compute power...
Concurrency in Numeric
Computation
ƒ These are essentially pure functional algorithms, but they
operate locally on mutable state
ƒ Haskell ST, STRef solution enables encapsulating local
heaps and mutability within referentially-transparent code
ƒ These are the building blocks for implicitly parallel
programs
ƒ Estimate ~80% of CPU effort in Unreal can be parallelized
this way
In the future, we will write these
algorithms using referentially-
transparent constructs.
Numeric Computation Example:
Collision Detection
A typical collision detection algorithm takes a line
segment and determines when and where a point
moving along that line will collide with a (constant)
geometric dataset.
struct vec3
{
float x,y,z;
};
struct hit
{
bool DidCollide;
float Time;
vec3 Location;
};
hit collide(vec3 start,vec3 end);
Vec3 = data Vec3 float float float
Hit = data Hit float Vec3
collide :: (vec3,vec3)->Maybe Hit
Numeric Computation Example:
Collision Detection
ƒ Since collisionCheck is effects-free, it may be
executed in parallel with any other effects-free
computations.
ƒ Basic idea:
– The programmer supplies effect annotations to the compiler.
– The compiler verifies the annotations.
– Many viable implementations (Haskell’s Monadic effects,
effect typing, etc)
collide(start:Vec3,end:Vec3):?Hit
print(s:string)[#imperative]:void
A pure function
(the default)
Effectful functions require
explicit annotations
In a concurrent world, imperative is
the wrong default!
Concurrency in Gameplay Simulation
This is the hardest problem…
ƒ 10,00’s of objects
ƒ Each one contains mutable state
ƒ Each one updated 30 times per second
ƒ Each update touches 5-10 other objects
Manual synchronization (shared state concurrency)
is
hopelessly intractible here.
Solutions?
– Rewrite as referentially-transparent functions?
– Message-passing concurrency?
– Continue using the sequential, single-threaded approach?
Concurrency in Gameplay Simulation:
Software Transactional Memory
See “Composable memory transactions”;
Harris, Marlow, Peyton-Jones, Herlihy
The idea:
ƒ Update all objects concurrently in arbitrary order,
with each update wrapped in an atomic {...} block
ƒ With 10,000’s of updates, and 5-10 objects touched per
update, collisions will be low
ƒ ~2-4X STM performance overhead is acceptable:
if it enables our state-intensive code to scale to many threads,
it’s still a win
Claim: Transactions are the only plausible
solution to concurrent mutable state
Three Kinds of Code: Revisited
500 GFLOPS
5 GFLOPS
0.5 GFLOPS
FPU Usage
Implicit Data
Parallelism
Implicit
Thread
Parallelism
Software
Transactional
Memory
Parallelism
Lines of Code
CPU Budget
Languages
10,000
250,000
250,000
n/a
90%
10%
CG, HLSL
C++
C++, Scripting
Shading
Numeric
Computation
Game
Simulation
Parallelism and purity
Software Transactional Memory
Purely functional core
Physics, collision detection,
scene traversal, path finding, ..
Data Parallel Subset
Graphics shader programs
Game World State
On the Next Maintream Programming Language
Musings
There is a wonderful correspondence between:
ƒ Features that aid reliability
ƒ Features that enable concurrency.
Example:
ƒ Outlawing runtime exceptions through dependent types
– Out of bounds array access
– Null pointer dereference
– Integer overflow
Exceptions impose sequencing constraints on concurrent execution.
Dependent types and concurrency must
evolve simultaneously
Language Implications
Evaluation Strategy
ƒ Lenient evaluation is the right default.
ƒ Support lazy evaluation through explicit
suspend/evaluate constructs.
ƒ Eager evaluation is an optimization the compiler may
perform when it is safe to do so.
Language Implications
Effects Model
ƒ Purely Functional is the right default
ƒ Imperative constructs are vital features
that must be exposed through explicit
effects-typing constructs
ƒ Exceptions are an effect
Why not go one step further and define
partiality as an effect, thus creating a
foundational language subset suitable
for proofs?
Performance – Language Implications
Memory model
– Garbage collection should be the only option
Exception Model
– The Java/C# “exceptions everywhere” model
should be wholly abandoned
• All dereference and array accesses must be statically
verifyable, rather than causing sequenced exceptions
– No language construct except “throw” should
generate an exception
Syntax
Requirement:
ƒ Must not scare away mainstream programmers.
ƒ Lots of options.
int f{nat n}(int[] as,natrange<n> i)
{
return as[i];
}
f{n:nat}(as:[]int,i:nat<n)=as[i]
f :: forall n::nat. ([int],nat<n) -> int
f (xs,i) = xs !! i
C Family: Least scary,
but it’s a messy legacy
Haskell family: Quite scary :-)
Pascal/ML family:
Seems promising
A Brief History of Game Technology
1972 Pong (hardware)
1980 Zork (high level interpretted language)
1993 DOOM (C)
1998 Unreal (C++, Java-style scripting)
2005-6 Xbox 360, PlayStation 3
with 6-8 hardware threads
2009 Next console generation. Unification of the
CPU, GPU. Massive multi-core, data parallelism, etc.
The Coming Crisis in Computing
ƒ By 2009, game developers will face…
ƒ CPU’s with:
– 20+ cores
– 80+ hardware threads
– >1 TFLOP of computing power
ƒ GPU’s with general computing capabilities.
ƒ Game developers will be at the forefront.
ƒ If we are to program these devices
productively, you are our only hope!
Backup Slides
The Genius of Haskell
ƒ Algebraic Datatypes
– Unions done right
Compare to: C unions, Java union-like class
hierarchies
– Maybe t
C/Java option types are coupled to
pointer/reference types
ƒ IO, ST
– With STRef, you can write a pure function that
uses heaps and mutable state locally, verifyably
guaranteeing that those effects remain local.
The Genius of Haskell
ƒ Comprehensions
sort [] = []
sort (x:xs) = sort [y | y<-xs, y<x ] ++
[x ] ++
sort [y | y<-xs, y>=x]
int partition(int y[], int f, int l);
void quicksort(int x[], int first, int last) {
int pivIndex = 0;
if(first < last) {
pivIndex = partition(x,first, last);
quicksort(x,first,(pivIndex-1));
quicksort(x,(pivIndex+1),last);
}
}
int partition(int y[], int f, int l) {
int up,down,temp;
int cc;
int piv = y[f];
up = f;
down = l;
do {
while (y[up] <= piv && up < l) {
up++;
}
while (y[down] > piv ) {
down--;
}
if (up < down ) {
temp = y[up];
y[up] = y[down];
y[down] = temp;
}
} while (down > up);
temp = piv;
y[f] = y[down];
y[down] = piv;
return down;
}
Sorting in Haskell
Sorting in C
Why Haskell is Not My Favorite
Programming Language
ƒ The syntax is … scary
ƒ Lazy evaluation is a costly default
– But eager evaluation is too limiting
– Lenient evaluation would be an interesting default
ƒ Lists are the syntactically preferred
sequence type
– In the absence of lazy evaluation, arrays seem
preferable
Why Haskell is Not My Favorite
Programming Language
ƒ Type inference doesn’t scale
– To large hierarchies of open-world
modules
– To type system extensions
– To system-wide error propagation
f(x,y) = x+y
a=f(3,”4”)
f(int x,int y) = x+y
a=f(3,”4”)
ERROR - Cannot infer instance
*** Instance : Num [Char]
*** Expression : f (3,"4")
Parameter mismatch paremter 2 of call to f:
Expected: int
Got: “4”
…
…
???

More Related Content

Similar to The Next Mainstream Programming Language: A Game Developer's Perspective

02 direct3 d_pipeline
02 direct3 d_pipeline02 direct3 d_pipeline
02 direct3 d_pipelineGirish Ghate
 
Scalability for All: Unreal Engine* 4 with Intel
Scalability for All: Unreal Engine* 4 with Intel Scalability for All: Unreal Engine* 4 with Intel
Scalability for All: Unreal Engine* 4 with Intel Intel® Software
 
Simple Single Instruction Multiple Data (SIMD) with the Intel® Implicit SPMD ...
Simple Single Instruction Multiple Data (SIMD) with the Intel® Implicit SPMD ...Simple Single Instruction Multiple Data (SIMD) with the Intel® Implicit SPMD ...
Simple Single Instruction Multiple Data (SIMD) with the Intel® Implicit SPMD ...Intel® Software
 
The Ring programming language version 1.9 book - Part 58 of 210
The Ring programming language version 1.9 book - Part 58 of 210The Ring programming language version 1.9 book - Part 58 of 210
The Ring programming language version 1.9 book - Part 58 of 210Mahmoud Samir Fayed
 
Hacking with Reverse Engineering and Defense against it
Hacking with Reverse Engineering and Defense against it Hacking with Reverse Engineering and Defense against it
Hacking with Reverse Engineering and Defense against it Prakashchand Suthar
 
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT TalksMykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT TalksVadym Muliavka
 
고급컴파일러구성론_개레_230303.pptx
고급컴파일러구성론_개레_230303.pptx고급컴파일러구성론_개레_230303.pptx
고급컴파일러구성론_개레_230303.pptxssuser1e7611
 
Reverse code engineering
Reverse code engineeringReverse code engineering
Reverse code engineeringKrishs Patil
 
Optimizing unity games (Google IO 2014)
Optimizing unity games (Google IO 2014)Optimizing unity games (Google IO 2014)
Optimizing unity games (Google IO 2014)Alexander Dolbilov
 
Unit 1 c - all topics
Unit 1   c - all topicsUnit 1   c - all topics
Unit 1 c - all topicsveningstonk
 
Unmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeUnmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeDmitri Nesteruk
 
Skiron - Experiments in CPU Design in D
Skiron - Experiments in CPU Design in DSkiron - Experiments in CPU Design in D
Skiron - Experiments in CPU Design in DMithun Hunsur
 
Gdc 14 bringing unreal engine 4 to open_gl
Gdc 14 bringing unreal engine 4 to open_glGdc 14 bringing unreal engine 4 to open_gl
Gdc 14 bringing unreal engine 4 to open_glchangehee lee
 
Typhoon Managed Execution Toolkit
Typhoon Managed Execution ToolkitTyphoon Managed Execution Toolkit
Typhoon Managed Execution ToolkitDimitry Snezhkov
 
"Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft...
"Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft..."Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft...
"Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft...Dataconomy Media
 

Similar to The Next Mainstream Programming Language: A Game Developer's Perspective (20)

02 direct3 d_pipeline
02 direct3 d_pipeline02 direct3 d_pipeline
02 direct3 d_pipeline
 
Scalability for All: Unreal Engine* 4 with Intel
Scalability for All: Unreal Engine* 4 with Intel Scalability for All: Unreal Engine* 4 with Intel
Scalability for All: Unreal Engine* 4 with Intel
 
Simple Single Instruction Multiple Data (SIMD) with the Intel® Implicit SPMD ...
Simple Single Instruction Multiple Data (SIMD) with the Intel® Implicit SPMD ...Simple Single Instruction Multiple Data (SIMD) with the Intel® Implicit SPMD ...
Simple Single Instruction Multiple Data (SIMD) with the Intel® Implicit SPMD ...
 
The Ring programming language version 1.9 book - Part 58 of 210
The Ring programming language version 1.9 book - Part 58 of 210The Ring programming language version 1.9 book - Part 58 of 210
The Ring programming language version 1.9 book - Part 58 of 210
 
Hacking with Reverse Engineering and Defense against it
Hacking with Reverse Engineering and Defense against it Hacking with Reverse Engineering and Defense against it
Hacking with Reverse Engineering and Defense against it
 
Unit1 C
Unit1 CUnit1 C
Unit1 C
 
Unit1 C
Unit1 CUnit1 C
Unit1 C
 
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT TalksMykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
 
고급컴파일러구성론_개레_230303.pptx
고급컴파일러구성론_개레_230303.pptx고급컴파일러구성론_개레_230303.pptx
고급컴파일러구성론_개레_230303.pptx
 
Arduino reference
Arduino referenceArduino reference
Arduino reference
 
Reverse code engineering
Reverse code engineeringReverse code engineering
Reverse code engineering
 
MXNet Workshop
MXNet WorkshopMXNet Workshop
MXNet Workshop
 
Optimizing unity games (Google IO 2014)
Optimizing unity games (Google IO 2014)Optimizing unity games (Google IO 2014)
Optimizing unity games (Google IO 2014)
 
Unit 1 c - all topics
Unit 1   c - all topicsUnit 1   c - all topics
Unit 1 c - all topics
 
Unmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeUnmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/Invoke
 
Skiron - Experiments in CPU Design in D
Skiron - Experiments in CPU Design in DSkiron - Experiments in CPU Design in D
Skiron - Experiments in CPU Design in D
 
Gdc 14 bringing unreal engine 4 to open_gl
Gdc 14 bringing unreal engine 4 to open_glGdc 14 bringing unreal engine 4 to open_gl
Gdc 14 bringing unreal engine 4 to open_gl
 
Typhoon Managed Execution Toolkit
Typhoon Managed Execution ToolkitTyphoon Managed Execution Toolkit
Typhoon Managed Execution Toolkit
 
OpenGL (ES) debugging
OpenGL (ES) debuggingOpenGL (ES) debugging
OpenGL (ES) debugging
 
"Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft...
"Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft..."Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft...
"Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft...
 

Recently uploaded

Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfYashikaSharma391629
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 

Recently uploaded (20)

Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 

The Next Mainstream Programming Language: A Game Developer's Perspective

  • 1. The Next Mainstream Programming Language: A Game Developer’s Perspective The Next Mainstream The Next Mainstream Programming Language: Programming Language: A Game Developer A Game Developer’ ’s Perspective s Perspective Tim Sweeney Tim Sweeney Epic Games Epic Games
  • 2. Outline ƒ Game Development – Typical Process ƒ What’s in a game? – Game Simulation – Numeric Computation – Shading ƒ Where are today’s languages failing? – Concurrency – Reliability
  • 4. Game Development: Gears of War ƒ Resources – ~10 programmers – ~20 artists – ~24 month development cycle – ~$10M budget ƒ Software Dependencies – 1 middleware game engine – ~20 middleware libraries – OS graphics APIs, sound, input, etc
  • 5. Software Dependencies Gears of War Gameplay Code ~250,000 lines C++, script code Gears of War Gameplay Code ~250,000 lines C++, script code Unreal Engine 3 Middleware Game Engine ~250,000 lines C++ code Unreal Engine 3 Middleware Game Engine ~250,000 lines C++ code DirectX Graphics DirectX Graphics OpenAL Audio OpenAL Audio Ogg Vorbis Music Codec Ogg Vorbis Music Codec Speex Speech Codec Speex Speech Codec wx Widgets Window Library wx Widgets Window Library ZLib Data Compr- ession ZLib Data Compr- ession …
  • 6. Game Development: Platforms ƒ The typical Unreal Engine 3 game will ship on: – Xbox 360 – PlayStation 3 – Windows ƒ Some will also ship on: – Linux – MacOS
  • 7. What’s in a game? The obvious: ƒ Rendering ƒ Pixel shading ƒ Physics simulation, collision detection ƒ Game world simulation ƒ Artificial intelligence, path finding But it’s not just fun and games: ƒ Data persistence with versioning, streaming ƒ Distributed Computing (multiplayer game simulation) ƒ Visual content authoring tools ƒ Scripting and compiler technology ƒ User interfaces
  • 8. Three Kinds of Code ƒ Gameplay Simulation ƒ Numeric Computation ƒ Shading
  • 10. Gameplay Simulation ƒ Models the state of the game world as interacting objects evolve over time ƒ High-level, object-oriented code ƒ Written in C++ or scripting language ƒ Imperative programming style ƒ Usually garbage-collected
  • 11. Gameplay Simulation – The Numbers ƒ 30-60 updates (frames) per second ƒ ~1000 distinct gameplay classes – Contain imperative state – Contain member functions – Highly dynamic ƒ ~10,000 active gameplay objects ƒ Each time a gameplay object is updated, it typically touches 5-10 other objects
  • 12. Numeric Computation ƒ Algorithms: – Scene graph traversal – Physics simulation – Collision Detection – Path Finding – Sound Propagation ƒ Low-level, high-performance code ƒ Written in C++ with SIMD intrinsics ƒ Essentially functional – Transforms a small input data set to a small output data set, making use of large constant data structures.
  • 14. Shading ƒ Generates pixel and vertex attributes ƒ Written in HLSL/CG shading language ƒ Runs on the GPU ƒ Inherently data-parallel – Control flow is statically known – “Embarassingly Parallel” – Current GPU’s are 16-wide to 48-wide!
  • 16. Shading – The Numbers ƒ Game runs at 30 FPS @ 1280x720p ƒ ~5,000 visible objects ƒ ~10M pixels rendered per frame – Per-pixel lighting and shadowing requires multiple rendering passes per object and per-light ƒ Typical pixel shader is ~100 instructions long ƒ Shader FPU’s are 4-wide SIMD ƒ ~500 GFLOPS compute power
  • 17. Three Kinds of Code FPU Usage Lines of Code CPU Budget Languages 500 GFLOPS 5 GFLOPS 0.5 GFLOPS 10,000 250,000 250,000 n/a 90% 10% CG, HLSL C++ C++, Scripting Shading Numeric Computation Game Simulation
  • 18. What are the hard problems? ƒ Performance – When updating 10,000 objects at 60 FPS, everything is performance-sensitive ƒ Modularity – Very important with ~10-20 middleware libraries per game ƒ Reliability – Error-prone language / type system leads to wasted effort finding trivial bugs – Significantly impacts productivity ƒ Concurrency – Hardware supports 6-8 threads – C++ is ill-equipped for concurrency
  • 19.
  • 20. Performance ƒ When updating 10,000 objects at 60 FPS, everything is performance-sensitive ƒ But: – Productivity is just as important – Will gladly sacrifice 10% of our performance for 10% higher productivity – We never use assembly language ƒ There is not a simple set of “hotspots” to optimize! That’s all!
  • 21.
  • 22. Unreal’s game framework package UnrealEngine; class Actor { int Health; void TakeDamage(int Amount) { Health = Health – Amount; if (Health<0) Die(); } } class Player extends Actor { string PlayerName; socket NetworkConnection; } Gameplay module Base class of gameplay objects Members
  • 24. Software Frameworks ƒ The Problem: Users of a framework need to extend the functionality of the framework’s base classes! ƒ The workarounds: – Modify the source …and modify it again with each new version – Add references to payload classes, and dynamically cast them at runtime to the appropriate types.
  • 25. Software Frameworks ƒ The Problem: Users of a framework want to extend the functionality of the framework’s base classes! ƒ The workarounds: – Modify the source …and modify it again with each new version – Add references to payload classes, and dynamically cast them at runtime to the appropriate types. – These are all error-prone: Can the compiler help us here?
  • 26. What we would like to write… package Engine; class Actor { int Health; … } class Player extends Actor { … } class Inventory extends Actor { … } Base Framework Package GearsOfWar extends Engine; class Actor extends Engine.Actor { // Here we can add new members // to the base class. … } class Player extends Engine.Player { // Thus virtually inherits from // GearsOfWar.Actor … } class Gun extends GearsOfWar.Inventory { … } Extended Framework The basic goal: To extend an entire software framework’s class hierarchy in parallel, in an open-world system.
  • 27. Or: If the compiler doesn’t beep, my program should work
  • 28. Dynamic Failure in Mainstream Languages Vertex[] Transform (Vertex[] Vertices, int[] Indices, Matrix m) { Vertex[] Result = new Vertex[Indices.length]; for(int i=0; i<Indices.length; i++) Result[i] = Transform(m,Vertices[Indices[i]]); return Result; }; Example (C#): Given a vertex array and an index array, we read and transform the indexed vertices into a new array. What can possibly go wrong?
  • 29. Dynamic Failure in Mainstream Languages Vertex[] Transform (Vertex[] Vertices, int[] Indices, Matrix m) { Vertex[] Result = new Vertex[Indices.length]; for(int i=0; i<Indices.length; i++) Result[i] = Transform(m,Vertices[Indices[i]]); return Result; }; May be NULL May be NULL May contain indices outside of the range of the Vertex array May be NULL Array access might be out of bounds Will the compiler realize this can’t fail? Could dereference a null pointer Our code is littered with runtime failure cases, Yet the compiler remains silent!
  • 30. Dynamic Failure in Mainstream Languages Solved problems: ƒ Random memory overwrites ƒ Memory leaks Solveable: ƒ Accessing arrays out-of-bounds ƒ Dereferencing null pointers ƒ Integer overflow ƒ Accessing uninitialized variables 50% of the bugs in Unreal can be traced to these problems!
  • 31. What we would like to write… Transform{n:nat}(Vertices:[n]Vertex, Indices:[]nat<n, m:Matrix):[]Vertex= for each(i in Indices) Transform(m,Vertices[i]) Universally quantify over all natural numbers An array of exactly known size An index buffer containing natural numbers less than n Haskell-style array comprehension The only possible failure mode: divergence, if the call to Transform diverges.
  • 32. How might this work? ƒ Dependent types ƒ Dependent functions ƒ Universal quantification int nat nat<n Sum{n:nat}(xs:[n]int)=.. a=Sum([7,8,9]) Sum(n:nat,xs:[n]int)=.. a=Sum(3,[7,8,9]) The Integers The Natural Numbers The Natural Numbers less than n, where n may be a variable! Explicit type/value dependency between function parameters
  • 33. How might this work? ƒ Separating the “pointer to t” concept from the “optional value of t” concept ƒ Comprehensions (a la Haskell), for safely traversing and generating collections xp:^int xo:?int xpo:?^int A pointer to an integer An optional integer An optional pointer to an integer! Successors(xs:[]int):[]int= foreach(x in xs) x+1
  • 34. How might this work? A guarded casting mechanism for cases where need a safe “escape”: All potential failure must be explicitly handled, but we lose no expressiveness. GetElement(as:[]string, i:int):string= if(n:nat<as.length=i) as[n] else “Index Out of Bounds” Here, we cast i to type of natural numbers bounded by the length of as, and bind the result to n We can only access i within this context If the cast fails, we execute the else-branch
  • 35. Analysis of the Unreal code ƒ Usage of integer variables in Unreal: – 90% of integer variables in Unreal exist to index into arrays • 80% could be dependently-typed explicitly, guaranteeing safe array access without casting. • 10% would require casts upon array access. – The other 10% are used for: • Computing summary statistics • Encoding bit flags • Various forms of low-level hackery ƒ “For” loops in Unreal: – 40% are functional comprehensions – 50% are functional folds
  • 36. Accessing uninitialized variables ƒ Can we make this work? This is a frequent bug. Data structures are often rearranged, changing the initialization order. ƒ Lessons from Haskell: – Lazy evaluation enables correct out-of-order evaluation – Accessing circularly entailed values causes thunk reentry (divergence), rather than just returning the wrong value ƒ Lesson from Id90: Lenient evaluation is sufficient to guarantee this class MyClass { const int a=c+1; const int b=7; const int c=b+1; } MyClass myvalue = new C; // What is myvalue.a?
  • 37. Dynamic Failure: Conclusion Reasonable type-system extensions could statically eliminate all: ƒ Out-of-bounds array access ƒ Null pointer dereference ƒ Integer overflow ƒ Accessing of uninitialized variables See Haskell for excellent implementation of: – Comprehensions – Option types via Maybe – Non-NULL references via IORef, STRef – Out-of-order initialization
  • 38. Integer overflow The Natural Numbers Factoid: C# exposes more than 10 integer-like data types, none of which are those defined by (Pythagoras, 500BC). In the future, can we get integers right? data Nat = Zero | Succ Nat
  • 39. Can we get integers right? Neat Trick: ƒ In a machine word (size 2n), encode an integer ±2n-1 or a pointer to a variable-precision integer ƒ Thus “small” integers carry no storage cost ƒ Additional access cost is ~5 CPU instructions But: ƒ A natural number bounded so as to index into an active array is guaranteed to fit within the machine word size (the array is the proof of this!) and thus requires no special encoding. ƒ Since ~80% of integers can dependently-typed to access into an array, the amortized cost is ~1 CPU instruction per integer operation. This could be a viable tradeoff
  • 41. The C++/Java/C# Model: “Shared State Concurrency” ƒ The Idea: – Any thread can modify any state at any time. – All synchronization is explicit, manual. – No compile-time verification of correctness properties: • Deadlock-free • Race-free
  • 42. The C++/Java/C# Model: “Shared State Concurrency” ƒ This is hard! ƒ How we cope in Unreal Engine 3: – 1 main thread responsible for doing all work we can’t hope to safely multithread – 1 heavyweight rendering thread – A pool of 4-6 helper threads • Dynamically allocate them to simple tasks. – “Program Very Carefully!” ƒ Huge productivity burden ƒ Scales poorly to thread counts There must be a better way!
  • 43. Three Kinds of Code: Revisited ƒ Gameplay Simulation – Gratuitous use of mutable state – 10,000’s of objects must be updated – Typical object update touches 5-10 other objects ƒ Numeric Computation – Computations are purely functional – But they use state locally during computations ƒ Shading – Already implicitly data parallel
  • 44. Concurrency in Shading ƒ Look at the solution of CG/HLSL: – New programming language aimed at “Embarassingly Parallel” shader programming – Its constructs map naturally to a data-parallel implementation – Static control flow (conditionals supported via masking)
  • 45. Concurrency in Shading Conclusion: The problem of data-parallel concurrency is effectively solved(!) “Proof”: Xbox 360 games are running with 48-wide data shader programs utilizing half a Teraflop of compute power...
  • 46. Concurrency in Numeric Computation ƒ These are essentially pure functional algorithms, but they operate locally on mutable state ƒ Haskell ST, STRef solution enables encapsulating local heaps and mutability within referentially-transparent code ƒ These are the building blocks for implicitly parallel programs ƒ Estimate ~80% of CPU effort in Unreal can be parallelized this way In the future, we will write these algorithms using referentially- transparent constructs.
  • 47. Numeric Computation Example: Collision Detection A typical collision detection algorithm takes a line segment and determines when and where a point moving along that line will collide with a (constant) geometric dataset. struct vec3 { float x,y,z; }; struct hit { bool DidCollide; float Time; vec3 Location; }; hit collide(vec3 start,vec3 end); Vec3 = data Vec3 float float float Hit = data Hit float Vec3 collide :: (vec3,vec3)->Maybe Hit
  • 48. Numeric Computation Example: Collision Detection ƒ Since collisionCheck is effects-free, it may be executed in parallel with any other effects-free computations. ƒ Basic idea: – The programmer supplies effect annotations to the compiler. – The compiler verifies the annotations. – Many viable implementations (Haskell’s Monadic effects, effect typing, etc) collide(start:Vec3,end:Vec3):?Hit print(s:string)[#imperative]:void A pure function (the default) Effectful functions require explicit annotations In a concurrent world, imperative is the wrong default!
  • 49. Concurrency in Gameplay Simulation This is the hardest problem… ƒ 10,00’s of objects ƒ Each one contains mutable state ƒ Each one updated 30 times per second ƒ Each update touches 5-10 other objects Manual synchronization (shared state concurrency) is hopelessly intractible here. Solutions? – Rewrite as referentially-transparent functions? – Message-passing concurrency? – Continue using the sequential, single-threaded approach?
  • 50. Concurrency in Gameplay Simulation: Software Transactional Memory See “Composable memory transactions”; Harris, Marlow, Peyton-Jones, Herlihy The idea: ƒ Update all objects concurrently in arbitrary order, with each update wrapped in an atomic {...} block ƒ With 10,000’s of updates, and 5-10 objects touched per update, collisions will be low ƒ ~2-4X STM performance overhead is acceptable: if it enables our state-intensive code to scale to many threads, it’s still a win Claim: Transactions are the only plausible solution to concurrent mutable state
  • 51. Three Kinds of Code: Revisited 500 GFLOPS 5 GFLOPS 0.5 GFLOPS FPU Usage Implicit Data Parallelism Implicit Thread Parallelism Software Transactional Memory Parallelism Lines of Code CPU Budget Languages 10,000 250,000 250,000 n/a 90% 10% CG, HLSL C++ C++, Scripting Shading Numeric Computation Game Simulation
  • 52. Parallelism and purity Software Transactional Memory Purely functional core Physics, collision detection, scene traversal, path finding, .. Data Parallel Subset Graphics shader programs Game World State
  • 53. On the Next Maintream Programming Language
  • 54. Musings There is a wonderful correspondence between: ƒ Features that aid reliability ƒ Features that enable concurrency. Example: ƒ Outlawing runtime exceptions through dependent types – Out of bounds array access – Null pointer dereference – Integer overflow Exceptions impose sequencing constraints on concurrent execution. Dependent types and concurrency must evolve simultaneously
  • 55. Language Implications Evaluation Strategy ƒ Lenient evaluation is the right default. ƒ Support lazy evaluation through explicit suspend/evaluate constructs. ƒ Eager evaluation is an optimization the compiler may perform when it is safe to do so.
  • 56. Language Implications Effects Model ƒ Purely Functional is the right default ƒ Imperative constructs are vital features that must be exposed through explicit effects-typing constructs ƒ Exceptions are an effect Why not go one step further and define partiality as an effect, thus creating a foundational language subset suitable for proofs?
  • 57. Performance – Language Implications Memory model – Garbage collection should be the only option Exception Model – The Java/C# “exceptions everywhere” model should be wholly abandoned • All dereference and array accesses must be statically verifyable, rather than causing sequenced exceptions – No language construct except “throw” should generate an exception
  • 58. Syntax Requirement: ƒ Must not scare away mainstream programmers. ƒ Lots of options. int f{nat n}(int[] as,natrange<n> i) { return as[i]; } f{n:nat}(as:[]int,i:nat<n)=as[i] f :: forall n::nat. ([int],nat<n) -> int f (xs,i) = xs !! i C Family: Least scary, but it’s a messy legacy Haskell family: Quite scary :-) Pascal/ML family: Seems promising
  • 59.
  • 60. A Brief History of Game Technology 1972 Pong (hardware) 1980 Zork (high level interpretted language) 1993 DOOM (C) 1998 Unreal (C++, Java-style scripting) 2005-6 Xbox 360, PlayStation 3 with 6-8 hardware threads 2009 Next console generation. Unification of the CPU, GPU. Massive multi-core, data parallelism, etc.
  • 61. The Coming Crisis in Computing ƒ By 2009, game developers will face… ƒ CPU’s with: – 20+ cores – 80+ hardware threads – >1 TFLOP of computing power ƒ GPU’s with general computing capabilities. ƒ Game developers will be at the forefront. ƒ If we are to program these devices productively, you are our only hope!
  • 62.
  • 64. The Genius of Haskell ƒ Algebraic Datatypes – Unions done right Compare to: C unions, Java union-like class hierarchies – Maybe t C/Java option types are coupled to pointer/reference types ƒ IO, ST – With STRef, you can write a pure function that uses heaps and mutable state locally, verifyably guaranteeing that those effects remain local.
  • 65. The Genius of Haskell ƒ Comprehensions sort [] = [] sort (x:xs) = sort [y | y<-xs, y<x ] ++ [x ] ++ sort [y | y<-xs, y>=x] int partition(int y[], int f, int l); void quicksort(int x[], int first, int last) { int pivIndex = 0; if(first < last) { pivIndex = partition(x,first, last); quicksort(x,first,(pivIndex-1)); quicksort(x,(pivIndex+1),last); } } int partition(int y[], int f, int l) { int up,down,temp; int cc; int piv = y[f]; up = f; down = l; do { while (y[up] <= piv && up < l) { up++; } while (y[down] > piv ) { down--; } if (up < down ) { temp = y[up]; y[up] = y[down]; y[down] = temp; } } while (down > up); temp = piv; y[f] = y[down]; y[down] = piv; return down; } Sorting in Haskell Sorting in C
  • 66. Why Haskell is Not My Favorite Programming Language ƒ The syntax is … scary ƒ Lazy evaluation is a costly default – But eager evaluation is too limiting – Lenient evaluation would be an interesting default ƒ Lists are the syntactically preferred sequence type – In the absence of lazy evaluation, arrays seem preferable
  • 67. Why Haskell is Not My Favorite Programming Language ƒ Type inference doesn’t scale – To large hierarchies of open-world modules – To type system extensions – To system-wide error propagation f(x,y) = x+y a=f(3,”4”) f(int x,int y) = x+y a=f(3,”4”) ERROR - Cannot infer instance *** Instance : Num [Char] *** Expression : f (3,"4") Parameter mismatch paremter 2 of call to f: Expected: int Got: “4” … … ???