SlideShare a Scribd company logo
1 of 89
Download to read offline
This slide deck was presented at Unite Berlin 2018.
This offline version includes numerous additional slides, cut
from the original presentation for brevity and/or time.
These extra slides contains more examples and data, but are
not essential for understanding the presentation.
Optimization & Best Practices:
Through The Ages
Ian Dundore
Unity Technologies
This guy again?
Spoiler Alert
• Scripting Performance
• Transforms
• Audio
• Animations
First:
An important message.
Even me. Especially me.
Profile everything.
Remember this?
oops.
• In the specific case of String.Equals, that advice is wrong!
• From a performance perspective, at least.
• For all other string comparisons, it’s right!
• Compare, StartsWith, EndsWith, IndexOf, etc.
• Again, from a performance perspective.
• (Psst! This is documented!)
https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#common-string-comparison-methods-in-net
Let’s test it.
Testing Considerations
• How does the code path differ with different inputs?
• What is the environment around the executing code?
• Runtime
• IL2CPP/Mono? .Net version?
• Hardware
• Pipeline depth, cache size, cache-line length
• # of cores, core affinity settings on threads, throttling
• What exactly is your test measuring?
Your Test Harness Matters!
Profiler.BeginSample(“Test A”);
for (int i=0; i<NUM_TESTS; ++i) {
DoAThing(i);
}
Profiler.EndSample();
int i = 0;
Profiler.BeginSample(“Test B”);
DoAThing(0);
while (i<NUM_TESTS) {
DoAThing(++i);
DoAThing(++i);
DoAThing(++i);
// … repeat a lot …
DoAThing(++i);
}
Profiler.EndSample();
Less Loop OverheadMore Loop Overhead
public bool Equals(String value) {
if (this == null)
throw new NullReferenceException();
if (value == null)
return false;
if (Object.ReferenceEquals(this, value))
return true;
if (this.Length != value.Length)
return false;
return EqualsHelper(this, value);
}
Mono’s String.cs (1)
What does EqualsHelper do?
• Uses unsafe code to pin strings to memory addresses.
• C-style integer comparison of raw bytes of the strings.
• Core is a special cache-friendly loop.
• 64-bit: Step through strings with a stride of 12 bytes.
while (length >= 12)
{
if (*(long*)a != *(long*)b) return false;
if (*(long*)(a+4) != *(long*)(b+4)) return false;
if (*(long*)(a+8) != *(long*)(b+8)) return false;
a += 12; b += 12; length -= 12;
}
public bool Equals(String value, StringComparison comparisonType) {
if (comparisonType < StringComparison.CurrentCulture ||
comparisonType > StringComparison.OrdinalIgnoreCase)
throw new ArgumentException(…);
Contract.EndContractBlock();
if ((Object)this == (Object)value) {
return true;
}
if ((Object)value == null) {
return false;
}
Mono’s String.cs (2)
switch (comparisonType) {
case StringComparison.CurrentCulture:
return (CultureInfo.CurrentCulture.CompareInfo.Compare(this,
value, CompareOptions.None) == 0);
case StringComparison.CurrentCultureIgnoreCase:
return (CultureInfo.CurrentCulture.CompareInfo.Compare(this,
value, CompareOptions.IgnoreCase) == 0);
case StringComparison.InvariantCulture:
return (CultureInfo.InvariantCulture.CompareInfo.Compare(this,
value, CompareOptions.None) == 0);
case StringComparison.InvariantCultureIgnoreCase:
return (CultureInfo.InvariantCulture.CompareInfo.Compare(this,
value, CompareOptions.IgnoreCase) == 0);
Mono’s String.cs (3)
case StringComparison.Ordinal:
if (this.Length != value.Length)
return false;
return EqualsHelper(this, value);
Mono’s String.cs (4)
But wait!
• For non-matching strings, length will often differ.
• But for length-invariant strings, first character usually differs.
• This optimization is found in CompareOrdinal, but not Equals.
public static int CompareOrdinal(String strA, String strB) {
if ((Object)strA == (Object)strB)
return 0;
if (strA == null)
return -1;
if (strB == null)
return 1;
// Most common case, first character is different.
if ((strA.m_firstChar - strB.m_firstChar) != 0)
return strA.m_firstChar - strB.m_firstChar;
return CompareOrdinalHelper(strA, strB);
}
This is getting silly.
public static int CompareOrdinal(String strA, int indexA,
String strB, int indexB, int length) {
if (strA == null || strB == null) {
if ((Object)strA==(Object)strB) { //they're both null;
return 0;
}
return (strA==null)? -1 : 1; //-1 if A is null, 1 if B is null.
}
return nativeCompareOrdinalEx(strA, indexA, strB, indexB, length);
}
An overload that goes almost directly to native code!
Test Design: 4 cases
• Case 1: Two identical strings.
• Case 2: Two strings of random characters of same length.
• Case 3: Two strings of random characters of same length.
• First characters identical, to bypass check in Compare.
• Case 4: Two strings of random characters, different lengths.
• Comparison’s worst case is bounded by the shorter string.
• Constrained range to 15-25 characters to be similar to above tests.
Mono 3.5
Identical Content
Identical Length
Random Content
Identical Length
First Char Equal
Identical Length
Random Content
Random Length
String.Equals 2.97 1.75 1.73 1.30
String.Equals
with Ordinal type
5.87 3.46 3.56 3.39
String.Compare 37.52 33.29 64.66 31.35
String.Compare
with Ordinal type
6.23 3.35 3.35 3.26
CompareOrdinal 5.68 3.10 3.18 2.99
CompareOrdinal
with Indices
5.53 3.30 3.42 3.95
Simple
Hand-Coded
5.46 1.75 2.18 1.40
100,000 comparisons. Timings in milliseconds.
Unity 2018.1.0f2, Windows Standalone, Mono 3.5, Core i7-3500K
Mono 3.5
Identical Content
Identical Length
Random Content
Identical Length
First Char Equal
Identical Length
Random Content
Random Length
String.Equals 3.23 1.80 1.82 1.21
String.Equals
with Ordinal type
3.84 2.13 2.03 1.38
String.Compare 34.72 28.70 63.03 29.74
String.Compare
with Ordinal type
5.16 1.75 2.68 1.65
CompareOrdinal 4.93 1.55 2.21 1.40
CompareOrdinal
with Indices
4.77 3.59 3.59 4.41
Simple
Hand-Coded
4.40 1.66 1.95 1.28
100,000 comparisons. Timings in milliseconds.
Unity 2018.1.0f2, Windows Standalone, Mono 4.6, Core i7-3500K
IL2CPP
Identical Content
Identical Length
Random Content
Identical Length
First Char Equal
Identical Length
Random Content
Random Length
String.Equals 2.61 1.26 1.27 0.95
String.Equals
with Ordinal type
5.38 3.80 3.84 3.66
String.Compare 39.12 29.32 60.56 28.01
String.Compare
with Ordinal type
4.84 3.58 3.62 3.52
CompareOrdinal 4.78 3.55 3.58 3.51
CompareOrdinal
with Indices
4.93 3.71 3.72 4.17
Simple
Hand-Coded
13.83 3.52 3.93 2.16
100,000 comparisons. Timings in milliseconds.
Unity 2018.1.0f2, Windows Standalone, IL2CPP 3.5, Core i7-6700K
IL2CPP
Identical Content
Identical Length
Random Content
Identical Length
First Char Equal
Identical Length
Random Content
Random Length
String.Equals 2.64 1.92 1.93 0.96
String.Equals
with Ordinal type
2.94 2.26 2.73 1.49
String.Compare 40.98 30.61 60.82 29.26
String.Compare
with Ordinal type
3.18 1.46 2.29 1.32
CompareOrdinal 2.99 1.18 2.06 1.12
CompareOrdinal
with Indices
5.56 3.93 4.08 4.41
Simple
Hand-Coded
14.14 3.78 4.14 2.35
100,000 comparisons. Timings in milliseconds.
Unity 2018.1.0f2, Windows Standalone, IL2CPP 4.6, Core i7-6700K
Raw Data
String.Equals/Random on Mono 3.5 = 1
Conclusions & more questions
• String.Equals clearly wins for plain string comparison.
• .NET 4.6 has improvements for String.Compare variants.
• Ordinal comparisons clearly win on culture-sensitive APIs.
• Use String.CompareOrdinal instead of String.Compare.
• Use StringComparison.Ordinal on other String APIs.
• How does this map across platforms?
IL2CPP
Identical Content
Identical Length
Random Content
Identical Length
First Char Equal
Identical Length
Random Content
Random Length
String.Equals 13.48 5.08 5.01 5.26
String.Equals
with Ordinal type
25.42 19.46 19.85 14.16
String.Compare 118.80 128.69 254.30 124.81
String.Compare
with Ordinal type
24.23 11.49 11.57 10.95
CompareOrdinal 23.92 11.09 11.54 10.75
CompareOrdinal
with Indices
23.79 14.76 18.62 15.05
Simple
Hand-Coded
58.02 12.04 21.86 8.13
100,000 comparisons. Timings in milliseconds.
Unity 2018.1.0f2, iOS, IL2CPP 3.5, iPad Mini 3
String.Equals/Random on given platform = 1
Very similar results, in this case.
Another tip!
• See a lot of time going to NullCheck in IL2CPP builds?
• Disable these checks in release builds!
• Works on types, methods & properties.
• Code is in IL2CppSetOptionAttribute.cs, under Unity install folder
[Il2CppSetOption(Option.NullChecks, false)]
public bool MyEquals(String strA, String strB) {
// …
}
IL2CPP
Identical Content
Identical Length
Random Content
Random Length
Normal 58.02 8.13
NullCheck
Disabled
53.02 7.03
100,000 comparisons. Timings in milliseconds.
Unity 2018.1.0f2, iOS, IL2CPP 3.5, iPad Mini 3
Small, but helpful.
Transforms
* no, not this kind of transform
5.3: Discrete Objects
A
B
C
D
Hierarchy
A
D
C
B
Memory
OnTransformChanged
• Internal message, broadcast each time a Transform changes
• Position, rotation, scale, parent, sibling order, etc.
• Tells other components to update their internal state
• PhysX/Box2D, UnityUI, Renderers (AABBs), etc.
• Repeated messages can cause performance problems
• Use Transform.SetPositionAndRotation (5.6+)
5.4+: Contiguous buffers
A
B
C
D
Hierarchy
A
B
C
D
Memory
TransformHierarchy structure
Enter the Dispatch
• TransformChangeDispatch was first introduced in 5.4
• Other systems migrated to use it, slowly.
• Renderers in 5.6
• Animators in 2017.1
• Physics in 2017.2
• RectTransforms in 2017.3
• OnTransformChanged was removed entirely in 2018.1
How Transforms are structured
• 1 TransformHierarchy structure represents a root Transform
• Contains buffers tracking data of all transforms in hierarchy
• TRS, indices for parents & siblings
• Interest bitmask & dirty bitmask
• Internal systems register interest & track state via specific bits
• Physics is one bit, renderer is another bit, etc.
• System walks affected parts of TransformHierarachy structure
• dirtyMask |= -1 & interestMask
When are async changes applied?
• TCD keeps a list of dirty TransformHierarchy pointers
• Systems request list of changed Transforms before running.
• e.g. Before FixedUpdate, before rendering, before animating.
• Use list to update internal system state.
• TCD iterates over list of dirty TransformHierarchies.
• Iterates over all Transforms to check each dirty bit.
Quick Reminder
• Buffer size: Transform.hierarchyCapacity
• Set before mass reparenting operations!
• Reparent & reposition during instantiate!
• GameObject.Instantiate( prefab, parent );
• GameObject.Instantiate( prefab, parent, position, rotation );
Split your hierarchies.
• Changing any Transform marks the whole Hierarchy dirty.
• Dirty hierarchies must be fully examined for change bits.
• Smaller hierarchies = more granular Hierarchy tracking.
• Smaller hierarchies = fewer Transforms to check.
• Fewer roots = more Transforms to check for changes.
• Change checks are jobified, but operate on roots.
Extreme cases.
UnparentedParented
100 Root GameObjects
+ 1000 empty GameObjects
+ 1 Cube w/ Rotation script
100,000 empty GameObjects
100 Cubes w/ Rotation script
A welcome effect.
Parented Unparented
Main Thread 553 ms 32 ms
Worker Threads 139 ms 14 ms
100 Rotating Cubes, 100k Empty GameObjects.
iPad Mini 3. CPU time used over 10 seconds.
This is just checking hierarchies!
Parented Unparented
Main Thread 1.77 ms 0.11 ms
100 Rotating Cubes, 100k Empty GameObjects.
iPad Mini 3. CPU time used over 10 seconds.
“PostLateUpdate.UpdateAllRenderers”
Transforms & Physics: 2017.2+
• 2017.1/older: Physics components were synced to Transforms.
• Each Transform change = expensive update of Physics scene.
• 2017.2/newer: Updates can be delayed to next FixedUpdate.
• Update Physics entities from set of changed Transforms.
• Re-indexing computations are batched.
• This could have side-effects!
• Move a Collider + immediately Raycast towards it? No bueno.
Physics.AutoSyncTransforms
• When true, forces legacy behavior.
• Colliders/Rigidbodies check for syncs on every Physics call.
• Yes, every Raycast, Spherecast, etc.
• Huge performance regression, if you’re not batching updates.
• When false, uses delayed-update behavior.
• Can force updates: Physics.SyncTransforms
• Default value is true in 2017.2 through 2018.2
• 2018.3 is the first version where the default is false.
void Update()
{
float rotAmt = 2f * Time.deltaTime;
Vector3 up = Vector3.up;
if (batched)
{
for(int i = 0; i < NUM_PARENTS; ++i)
rotators[i].Rotate(up, rotAmt);
for(int i = 0; i < NUM_PARENTS; ++i)
Physics.Raycast(Vector3.zero, Random.insideUnitSphere);
}
else
{
for (int i = 0; i < NUM_PARENTS; ++i)
{
rotators[i].Rotate(up, rotAmt);
Physics.Raycast(Vector3.zero, Random.insideUnitSphere);
}
}
}
A test.
“Batched”
“Immediate”
Seriously, a big effect.
Parented
Immediate
Unparented
Immediate
Parented
Batched
Unparented
Batched
Script 4450 ms 4270 ms 1980 ms 882 ms
Physics 1410 ms 1820 ms 1840 ms 1770 ms
100 Rotating Cubes, Rigidbodies, Trigger Box Colliders. 100k Empty GameObjects.
App Framerate: 30. Physics Timestep 0.04 sec.
iPad Mini 3. CPU time used over 10 seconds.
Audio
The Basics
• Unity uses FMOD internally.
• Audio decoding & playback occurs on separate threads.
• Unity supports a handful of codecs.
• PCM
• ADPCM
• Vorbis
• MP3
Audio “Load Type” Setting
• Decompress On Load
• Decoding & file I/O happen at load time only.
• Compressed In Memory
• Decoding happens during playback.
• Streamed
• File I/O & decoding happen during playback.
Every frame…
• Unity iterates over all active Audio Sources.
• Calculates distance to Listener(s).
• FMOD mixes active Audio Sources (“voices”).
• True volume = Volume setting * distance to listener * clip.
• If the clip is compressed, FMOD must decode audio data
• Chooses X loudest voices to mix together.
• X = “Real Voices” audio setting.
Everything is done in software.
• Decoding & mixing are done entirely in software.
• Mixing occurs on the FMOD thread.
• Decoding occurs at loading time or on the FMOD thread.
• All playing voices are evaluated and mixed.
• Max number of voices is controlled by Audio settings.
A trap.
This voice is Muted.
This voice is Active.
This voice will not be heard,
but the Clip must be processed.
A warning.
• AudioSystem.Update is Unity updating the AudioSources which
are submitted to FMOD for playback.
• Audio decoding does not show up in the Unity CPU Profiler.
Check both places!
• Decoding & mixing audio is in the details of the Audio profiler.
Audio CPU usage by codec.
10 Voices 100 Voices 500 Voices
PCM 1.5% 5.0% 5.7%
ADPCM 5.2% 16.6% 11.6%
MP3 13.3% 35.0% 23.3%
Vorbis 12.5% 30.3% 21.2%
Identical AudioClip, multiple AudioSources. MP3 & Vorbis Quality = 100.
WTF?
10 Voices 100 Voices 500 Voices
PCM 1.5% 5.0% 5.7%
ADPCM 5.2% 16.6% 11.6%
MP3 13.3% 35.0% 23.3%
Vorbis 12.5% 30.3% 21.2%
Identical AudioClip, multiple AudioSources. MP3 & Vorbis Quality = 100.
Oh. Profiler interference.
~Test time~ <(^^<) (>^^)>
• Identical 4 minute audio clip, copied 4 times.
• Once per codec under test.
• Varying number of AudioSources.
• Captured CPU time on main & FMOD threads
• Sum of CPU time consumed over 10 seconds real-time
Again.
10 Clips 100 Clips 500 Clips
PCM 95 ms 467 ms 2040 ms
ADPCM 89 ms 474 ms 2070 ms
MP3 84 ms 469 ms 2030 ms
Vorbis 93 ms 473 ms 1990 ms
CPU time on main thread, 10 seconds real-time.
With intensity.
10 Voices 100 Voices 500 Voices
PCM 214 ms 451 ms 634 ms
ADPCM 485 ms 1391 ms 1591 ms
MP3 1058 ms 4061 ms 4167 ms
Vorbis 1161 ms 3408 ms 3629 ms
CPU time on all FMOD threads, 10 seconds real-time.
Principles.
• Avoid having many audio sources set to Mute.
• Disable/Stop instead of Mute, if possible.
• If you can afford the memory overhead, Decompress on Load.
• Best for short clips that are frequently played.
• Avoid playing lots of compressed Clips, especially on mobile.
Or clamp the voice count.
10
Playing Clips
100
Playing Clips
500
Playing Clips
512 VV 318 ms 923 ms 2708 ms
100 VV 304 ms 905 ms 1087 ms
10 VV 315 ms 350 ms 495 ms
1 VV 173 ms 210 ms 361 ms
PCM. CPU time on FMOD + Main threads, 10 seconds real-time.
How, you ask?
public void SetNumVoices(int nv) {
var config = AudioSettings.GetConfiguration();
if(config.numVirtualVoices == nv)
return;
config.numVirtualVoices = nv;
config.numRealVoices = Mathf.Clamp(config.numRealVoices,
1, config.numVirtualVoices);
AudioSettings.Reset(config);
}
Just an example! Probably too simple for real use.
Animation & Animator
Animator
• Formerly called Mecanim.
• Graph of logical states.
• Blends between states.
• States contain animation clips and/or
blend trees.
• Animator component attached to
GameObject
• AnimatorController referenced by
Animator component.
Playables
• Technology underlying Animator & Timeline.
• Generic framework for “stuff that can be played back”.
• Animation clips, audio clips, video clips, etc.
• Docs: https://docs.unity3d.com/Manual/Playables.html
Animation
• Unity’s original animation system.
• Custom code
• Not based on Playables.
• Very simple: plays an animation clip.
• Can crossfade, loop.
Let’s test it.
The Test
• 100 GameObjects with Animator or Animation component
• Animator uses simple AnimatorController: 1 state, looping
• Animation plays back 1 AnimationClip, looping
0 ms
10 ms
20 ms
30 ms
1 100 200 300 400 500 600 700 800
Animation Animator
100 Components, Variable Curve Count, iPad Mini 3
TimeperFrame
How do cores affect it?
0 ms
1 ms
2 ms
3 ms
1 100 200 300 400 500 600 700 800
Animation Animator
100 Components, Variable Curve Count, Win10/Core i7
TimeperFrame Crossover on iPad Mini 3
0 ms
1 ms
2 ms
3 ms
1 100 200 300 400 500
Animation Animator
100 Curves, Variable Component Count, Win10/Core i7
TimeperFrame
Scaling Factors
• Performance is heavily dependent on curve & core count.
• Fewer cores: Animation retains advantage longer.
• More cores: Animator rapidly outperforms Animation.
• Both systems scale linearly as number of Components rises.
• “Best” system determined by target hardware vs curve count.
• Use Animation for simple animations.
• Use Animators for high curve counts or complex scenarios.
0 ms
13 ms
27 ms
40 ms
1 100 200 300 400 500
Animation Animator
100 Curves, Variable Component Count, iPad Mini 3
TimeperFrame
What about “constant” curves?
• Still interpolated at runtime.
• No measurable impact on CPU usage.
• Significant memory/file savings.
• Example: 11kb vs. 3.7kb for 100 position curves (XYZ)
What about Animator’s
cool features?
Be careful with Layers!
• The active state on each layer will be evaluated once per frame.
• Layer Weight does not matter.
• Weight=0? Still evaluated!
• This is to ensure that state is correct.
• Zero-weight layers = waste work
• Use layers sparingly!
(Yes, the docs are wrong.)
The Cost of Layering
1 Layer 2 Layers 3 Layers 4 Layers 5 Layers
Aggregate 1966 ms 2260 ms 2510 ms 2690 ms 2890 ms
Per Frame 10.08 ms 11.77 ms 12.86 ms 14.31 ms 17.65 ms
50 x “Ellen” from 3D Gamekit. Unity 2018.1.0f2.
Main Thread CPU time consumed during 10 Seconds Realtime.
iPad Mini 3.
What about Layer Masks?
Nope.
50 x “Ellen” from 3D Gamekit. Layers 2-5 Masked.
Main Thread CPU time consumed during 10 Seconds Realtime.
Unity 2018.1.0f2. iPad Mini 3.
1 Layer 2 Layers 3 Layers 4 Layers 5 Layers
Unmasked 1966 ms 2260 ms 2510 ms 2690 ms 2890 ms
60/108
Masked
1992 ms 2230 ms 2530 ms 2740 ms 2920 ms
Use the right rig!
• The Humanoid rig runs IK & retargeting calculations.
• The Generic rig does not.
1 Layer 2 Layers 3 Layers 4 Layers 5 Layers
Generic 1966 ms 2260 ms 2510 ms 2690 ms 2890 ms
Humanoid 2775 ms 3210 ms 3510 ms 3730 ms 4020 ms
Identical test to previous slide, different Rig import settings.
The pooling problem
• Animators reset their state when their GameObject is disabled.
• The only workaround? Disable Animator component, not
GameObject.
• Leads to messy side effects, like having to manage other
components (e.g. Colliders/Rigidbodies) manually.
• This made Animator-driven objects difficult to pool.
There’s an API to fix it, now!
• Animator.keepControllerStateOnDisable
• Available in 2018.1+
• If true, Animators do not discard data buffers when their
GameObject is disabled.
• Awesome for pooling!
• Careful of the higher memory usage of disabled Animators!
One Last Thing.
Thank these people!
Danke Schön!
Fragen?
Thank you!
Questions?

More Related Content

What's hot

Cypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdfCypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdfbacancytechnology
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012devCAT Studio, NEXON
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기Sang Heon Lee
 
Rendering AAA-Quality Characters of Project A1
Rendering AAA-Quality Characters of Project A1Rendering AAA-Quality Characters of Project A1
Rendering AAA-Quality Characters of Project A1Ki Hyunwoo
 
Unity mobile game performance profiling – using arm mobile studio
Unity mobile game performance profiling – using arm mobile studioUnity mobile game performance profiling – using arm mobile studio
Unity mobile game performance profiling – using arm mobile studioOwen Wu
 
확률의 구현법
확률의 구현법확률의 구현법
확률의 구현법
 
[IGC2018] 청강대 이득우 - 언리얼에디터확장을위해알아야할것들
[IGC2018] 청강대 이득우 - 언리얼에디터확장을위해알아야할것들[IGC2018] 청강대 이득우 - 언리얼에디터확장을위해알아야할것들
[IGC2018] 청강대 이득우 - 언리얼에디터확장을위해알아야할것들강 민우
 
NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀승명 양
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기흥배 최
 
Introduction to Integration Testing With Cypress
Introduction to Integration Testing With CypressIntroduction to Integration Testing With Cypress
Introduction to Integration Testing With CypressErez Cohen
 
그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기Yongha Kim
 
Windows IOCP vs Linux EPOLL Performance Comparison
Windows IOCP vs Linux EPOLL Performance ComparisonWindows IOCP vs Linux EPOLL Performance Comparison
Windows IOCP vs Linux EPOLL Performance ComparisonSeungmo Koo
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlinintelliyole
 
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션NHN FORWARD
 
[NDC2017] 딥러닝으로 게임 콘텐츠 제작하기 - VAE를 이용한 콘텐츠 생성 기법 연구 사례
[NDC2017] 딥러닝으로 게임 콘텐츠 제작하기 - VAE를 이용한 콘텐츠 생성 기법 연구 사례[NDC2017] 딥러닝으로 게임 콘텐츠 제작하기 - VAE를 이용한 콘텐츠 생성 기법 연구 사례
[NDC2017] 딥러닝으로 게임 콘텐츠 제작하기 - VAE를 이용한 콘텐츠 생성 기법 연구 사례Hwanhee Kim
 
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화Seungmo Koo
 
Cypress - Best Practices
Cypress - Best PracticesCypress - Best Practices
Cypress - Best PracticesBrian Mann
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템QooJuice
 
모바일 게임 최적화
모바일 게임 최적화 모바일 게임 최적화
모바일 게임 최적화 tartist
 
West Coast DevCon 2014: Game Programming in UE4 - Game Framework & Sample Pro...
West Coast DevCon 2014: Game Programming in UE4 - Game Framework & Sample Pro...West Coast DevCon 2014: Game Programming in UE4 - Game Framework & Sample Pro...
West Coast DevCon 2014: Game Programming in UE4 - Game Framework & Sample Pro...Gerke Max Preussner
 

What's hot (20)

Cypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdfCypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdf
 
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
조정훈, 게임 프로그래머를 위한 클래스 설계, NDC2012
 
[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기[NDC2016] TERA 서버의 Modern C++ 활용기
[NDC2016] TERA 서버의 Modern C++ 활용기
 
Rendering AAA-Quality Characters of Project A1
Rendering AAA-Quality Characters of Project A1Rendering AAA-Quality Characters of Project A1
Rendering AAA-Quality Characters of Project A1
 
Unity mobile game performance profiling – using arm mobile studio
Unity mobile game performance profiling – using arm mobile studioUnity mobile game performance profiling – using arm mobile studio
Unity mobile game performance profiling – using arm mobile studio
 
확률의 구현법
확률의 구현법확률의 구현법
확률의 구현법
 
[IGC2018] 청강대 이득우 - 언리얼에디터확장을위해알아야할것들
[IGC2018] 청강대 이득우 - 언리얼에디터확장을위해알아야할것들[IGC2018] 청강대 이득우 - 언리얼에디터확장을위해알아야할것들
[IGC2018] 청강대 이득우 - 언리얼에디터확장을위해알아야할것들
 
NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀
 
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
KGC 2016 오픈소스 네트워크 엔진 Super socket 사용하기
 
Introduction to Integration Testing With Cypress
Introduction to Integration Testing With CypressIntroduction to Integration Testing With Cypress
Introduction to Integration Testing With Cypress
 
그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기그럴듯한 랜덤 생성 컨텐츠 만들기
그럴듯한 랜덤 생성 컨텐츠 만들기
 
Windows IOCP vs Linux EPOLL Performance Comparison
Windows IOCP vs Linux EPOLL Performance ComparisonWindows IOCP vs Linux EPOLL Performance Comparison
Windows IOCP vs Linux EPOLL Performance Comparison
 
Idiomatic Kotlin
Idiomatic KotlinIdiomatic Kotlin
Idiomatic Kotlin
 
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
 
[NDC2017] 딥러닝으로 게임 콘텐츠 제작하기 - VAE를 이용한 콘텐츠 생성 기법 연구 사례
[NDC2017] 딥러닝으로 게임 콘텐츠 제작하기 - VAE를 이용한 콘텐츠 생성 기법 연구 사례[NDC2017] 딥러닝으로 게임 콘텐츠 제작하기 - VAE를 이용한 콘텐츠 생성 기법 연구 사례
[NDC2017] 딥러닝으로 게임 콘텐츠 제작하기 - VAE를 이용한 콘텐츠 생성 기법 연구 사례
 
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
게임서버프로그래밍 #7 - 패킷핸들링 및 암호화
 
Cypress - Best Practices
Cypress - Best PracticesCypress - Best Practices
Cypress - Best Practices
 
테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템테라로 살펴본 MMORPG의 논타겟팅 시스템
테라로 살펴본 MMORPG의 논타겟팅 시스템
 
모바일 게임 최적화
모바일 게임 최적화 모바일 게임 최적화
모바일 게임 최적화
 
West Coast DevCon 2014: Game Programming in UE4 - Game Framework & Sample Pro...
West Coast DevCon 2014: Game Programming in UE4 - Game Framework & Sample Pro...West Coast DevCon 2014: Game Programming in UE4 - Game Framework & Sample Pro...
West Coast DevCon 2014: Game Programming in UE4 - Game Framework & Sample Pro...
 

Similar to Unity's Evolving Best Practices

C# 101: Intro to Programming with C#
C# 101: Intro to Programming with C#C# 101: Intro to Programming with C#
C# 101: Intro to Programming with C#Hawkman Academy
 
Net framework session01
Net framework session01Net framework session01
Net framework session01Vivek chan
 
Improving Code Quality Through Effective Review Process
Improving Code Quality Through Effective  Review ProcessImproving Code Quality Through Effective  Review Process
Improving Code Quality Through Effective Review ProcessDr. Syed Hassan Amin
 
ParaSail
ParaSail  ParaSail
ParaSail AdaCore
 
Unmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeUnmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeDmitri Nesteruk
 
Headache from using mathematical software
Headache from using mathematical softwareHeadache from using mathematical software
Headache from using mathematical softwarePVS-Studio
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987乐群 陈
 
PVS-Studio and static code analysis technique
PVS-Studio and static code analysis techniquePVS-Studio and static code analysis technique
PVS-Studio and static code analysis techniqueAndrey Karpov
 
Peyton jones-2011-parallel haskell-the_future
Peyton jones-2011-parallel haskell-the_futurePeyton jones-2011-parallel haskell-the_future
Peyton jones-2011-parallel haskell-the_futureTakayuki Muranushi
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSkills Matter
 
Compiler optimizations based on call-graph flattening
Compiler optimizations based on call-graph flatteningCompiler optimizations based on call-graph flattening
Compiler optimizations based on call-graph flatteningCAFxX
 
SPARKNaCl: A verified, fast cryptographic library
SPARKNaCl: A verified, fast cryptographic librarySPARKNaCl: A verified, fast cryptographic library
SPARKNaCl: A verified, fast cryptographic libraryAdaCore
 
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
 
parellel computing
parellel computingparellel computing
parellel computingkatakdound
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)David McCarter
 
Introduction Machine Learning by MyLittleAdventure
Introduction Machine Learning by MyLittleAdventureIntroduction Machine Learning by MyLittleAdventure
Introduction Machine Learning by MyLittleAdventuremylittleadventure
 
Two methods for optimising cognitive model parameters
Two methods for optimising cognitive model parametersTwo methods for optimising cognitive model parameters
Two methods for optimising cognitive model parametersUniversity of Huddersfield
 

Similar to Unity's Evolving Best Practices (20)

C# 101: Intro to Programming with C#
C# 101: Intro to Programming with C#C# 101: Intro to Programming with C#
C# 101: Intro to Programming with C#
 
Net framework session01
Net framework session01Net framework session01
Net framework session01
 
Improving Code Quality Through Effective Review Process
Improving Code Quality Through Effective  Review ProcessImproving Code Quality Through Effective  Review Process
Improving Code Quality Through Effective Review Process
 
ParaSail
ParaSail  ParaSail
ParaSail
 
Unmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/InvokeUnmanaged Parallelization via P/Invoke
Unmanaged Parallelization via P/Invoke
 
Headache from using mathematical software
Headache from using mathematical softwareHeadache from using mathematical software
Headache from using mathematical software
 
Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987Compiler2016 by abcdabcd987
Compiler2016 by abcdabcd987
 
Modern C++
Modern C++Modern C++
Modern C++
 
PVS-Studio and static code analysis technique
PVS-Studio and static code analysis techniquePVS-Studio and static code analysis technique
PVS-Studio and static code analysis technique
 
Code Tuning
Code TuningCode Tuning
Code Tuning
 
Peyton jones-2011-parallel haskell-the_future
Peyton jones-2011-parallel haskell-the_futurePeyton jones-2011-parallel haskell-the_future
Peyton jones-2011-parallel haskell-the_future
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelism
 
Compiler optimizations based on call-graph flattening
Compiler optimizations based on call-graph flatteningCompiler optimizations based on call-graph flattening
Compiler optimizations based on call-graph flattening
 
SPARKNaCl: A verified, fast cryptographic library
SPARKNaCl: A verified, fast cryptographic librarySPARKNaCl: A verified, fast cryptographic library
SPARKNaCl: A verified, fast cryptographic library
 
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
 
parellel computing
parellel computingparellel computing
parellel computing
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)
 
Code Metrics
Code MetricsCode Metrics
Code Metrics
 
Introduction Machine Learning by MyLittleAdventure
Introduction Machine Learning by MyLittleAdventureIntroduction Machine Learning by MyLittleAdventure
Introduction Machine Learning by MyLittleAdventure
 
Two methods for optimising cognitive model parameters
Two methods for optimising cognitive model parametersTwo methods for optimising cognitive model parameters
Two methods for optimising cognitive model parameters
 

More from Unity Technologies

Build Immersive Worlds in Virtual Reality
Build Immersive Worlds  in Virtual RealityBuild Immersive Worlds  in Virtual Reality
Build Immersive Worlds in Virtual RealityUnity Technologies
 
Augmenting reality: Bring digital objects into the real world
Augmenting reality: Bring digital objects into the real worldAugmenting reality: Bring digital objects into the real world
Augmenting reality: Bring digital objects into the real worldUnity Technologies
 
Let’s get real: An introduction to AR, VR, MR, XR and more
Let’s get real: An introduction to AR, VR, MR, XR and moreLet’s get real: An introduction to AR, VR, MR, XR and more
Let’s get real: An introduction to AR, VR, MR, XR and moreUnity Technologies
 
Using synthetic data for computer vision model training
Using synthetic data for computer vision model trainingUsing synthetic data for computer vision model training
Using synthetic data for computer vision model trainingUnity Technologies
 
The Tipping Point: How Virtual Experiences Are Transforming Global Industries
The Tipping Point: How Virtual Experiences Are Transforming Global IndustriesThe Tipping Point: How Virtual Experiences Are Transforming Global Industries
The Tipping Point: How Virtual Experiences Are Transforming Global IndustriesUnity Technologies
 
Unity Roadmap 2020: Live games
Unity Roadmap 2020: Live games Unity Roadmap 2020: Live games
Unity Roadmap 2020: Live games Unity Technologies
 
Unity Roadmap 2020: Core Engine & Creator Tools
Unity Roadmap 2020: Core Engine & Creator ToolsUnity Roadmap 2020: Core Engine & Creator Tools
Unity Roadmap 2020: Core Engine & Creator ToolsUnity Technologies
 
How ABB shapes the future of industry with Microsoft HoloLens and Unity - Uni...
How ABB shapes the future of industry with Microsoft HoloLens and Unity - Uni...How ABB shapes the future of industry with Microsoft HoloLens and Unity - Uni...
How ABB shapes the future of industry with Microsoft HoloLens and Unity - Uni...Unity Technologies
 
Unity XR platform has a new architecture – Unite Copenhagen 2019
Unity XR platform has a new architecture – Unite Copenhagen 2019Unity XR platform has a new architecture – Unite Copenhagen 2019
Unity XR platform has a new architecture – Unite Copenhagen 2019Unity Technologies
 
Turn Revit Models into real-time 3D experiences
Turn Revit Models into real-time 3D experiencesTurn Revit Models into real-time 3D experiences
Turn Revit Models into real-time 3D experiencesUnity Technologies
 
How Daimler uses mobile mixed realities for training and sales - Unite Copenh...
How Daimler uses mobile mixed realities for training and sales - Unite Copenh...How Daimler uses mobile mixed realities for training and sales - Unite Copenh...
How Daimler uses mobile mixed realities for training and sales - Unite Copenh...Unity Technologies
 
How Volvo embraced real-time 3D and shook up the auto industry- Unite Copenha...
How Volvo embraced real-time 3D and shook up the auto industry- Unite Copenha...How Volvo embraced real-time 3D and shook up the auto industry- Unite Copenha...
How Volvo embraced real-time 3D and shook up the auto industry- Unite Copenha...Unity Technologies
 
QA your code: The new Unity Test Framework – Unite Copenhagen 2019
QA your code: The new Unity Test Framework – Unite Copenhagen 2019QA your code: The new Unity Test Framework – Unite Copenhagen 2019
QA your code: The new Unity Test Framework – Unite Copenhagen 2019Unity Technologies
 
Engineering.com webinar: Real-time 3D and digital twins: The power of a virtu...
Engineering.com webinar: Real-time 3D and digital twins: The power of a virtu...Engineering.com webinar: Real-time 3D and digital twins: The power of a virtu...
Engineering.com webinar: Real-time 3D and digital twins: The power of a virtu...Unity Technologies
 
Supplying scalable VR training applications with Innoactive - Unite Copenhage...
Supplying scalable VR training applications with Innoactive - Unite Copenhage...Supplying scalable VR training applications with Innoactive - Unite Copenhage...
Supplying scalable VR training applications with Innoactive - Unite Copenhage...Unity Technologies
 
XR and real-time 3D in automotive digital marketing strategies | Visionaries ...
XR and real-time 3D in automotive digital marketing strategies | Visionaries ...XR and real-time 3D in automotive digital marketing strategies | Visionaries ...
XR and real-time 3D in automotive digital marketing strategies | Visionaries ...Unity Technologies
 
Real-time CG animation in Unity: unpacking the Sherman project - Unite Copenh...
Real-time CG animation in Unity: unpacking the Sherman project - Unite Copenh...Real-time CG animation in Unity: unpacking the Sherman project - Unite Copenh...
Real-time CG animation in Unity: unpacking the Sherman project - Unite Copenh...Unity Technologies
 
Creating next-gen VR and MR experiences using Varjo VR-1 and XR-1 - Unite Cop...
Creating next-gen VR and MR experiences using Varjo VR-1 and XR-1 - Unite Cop...Creating next-gen VR and MR experiences using Varjo VR-1 and XR-1 - Unite Cop...
Creating next-gen VR and MR experiences using Varjo VR-1 and XR-1 - Unite Cop...Unity Technologies
 
What's ahead for film and animation with Unity 2020 - Unite Copenhagen 2019
What's ahead for film and animation with Unity 2020 - Unite Copenhagen 2019What's ahead for film and animation with Unity 2020 - Unite Copenhagen 2019
What's ahead for film and animation with Unity 2020 - Unite Copenhagen 2019Unity Technologies
 
How to Improve Visual Rendering Quality in VR - Unite Copenhagen 2019
How to Improve Visual Rendering Quality in VR - Unite Copenhagen 2019How to Improve Visual Rendering Quality in VR - Unite Copenhagen 2019
How to Improve Visual Rendering Quality in VR - Unite Copenhagen 2019Unity Technologies
 

More from Unity Technologies (20)

Build Immersive Worlds in Virtual Reality
Build Immersive Worlds  in Virtual RealityBuild Immersive Worlds  in Virtual Reality
Build Immersive Worlds in Virtual Reality
 
Augmenting reality: Bring digital objects into the real world
Augmenting reality: Bring digital objects into the real worldAugmenting reality: Bring digital objects into the real world
Augmenting reality: Bring digital objects into the real world
 
Let’s get real: An introduction to AR, VR, MR, XR and more
Let’s get real: An introduction to AR, VR, MR, XR and moreLet’s get real: An introduction to AR, VR, MR, XR and more
Let’s get real: An introduction to AR, VR, MR, XR and more
 
Using synthetic data for computer vision model training
Using synthetic data for computer vision model trainingUsing synthetic data for computer vision model training
Using synthetic data for computer vision model training
 
The Tipping Point: How Virtual Experiences Are Transforming Global Industries
The Tipping Point: How Virtual Experiences Are Transforming Global IndustriesThe Tipping Point: How Virtual Experiences Are Transforming Global Industries
The Tipping Point: How Virtual Experiences Are Transforming Global Industries
 
Unity Roadmap 2020: Live games
Unity Roadmap 2020: Live games Unity Roadmap 2020: Live games
Unity Roadmap 2020: Live games
 
Unity Roadmap 2020: Core Engine & Creator Tools
Unity Roadmap 2020: Core Engine & Creator ToolsUnity Roadmap 2020: Core Engine & Creator Tools
Unity Roadmap 2020: Core Engine & Creator Tools
 
How ABB shapes the future of industry with Microsoft HoloLens and Unity - Uni...
How ABB shapes the future of industry with Microsoft HoloLens and Unity - Uni...How ABB shapes the future of industry with Microsoft HoloLens and Unity - Uni...
How ABB shapes the future of industry with Microsoft HoloLens and Unity - Uni...
 
Unity XR platform has a new architecture – Unite Copenhagen 2019
Unity XR platform has a new architecture – Unite Copenhagen 2019Unity XR platform has a new architecture – Unite Copenhagen 2019
Unity XR platform has a new architecture – Unite Copenhagen 2019
 
Turn Revit Models into real-time 3D experiences
Turn Revit Models into real-time 3D experiencesTurn Revit Models into real-time 3D experiences
Turn Revit Models into real-time 3D experiences
 
How Daimler uses mobile mixed realities for training and sales - Unite Copenh...
How Daimler uses mobile mixed realities for training and sales - Unite Copenh...How Daimler uses mobile mixed realities for training and sales - Unite Copenh...
How Daimler uses mobile mixed realities for training and sales - Unite Copenh...
 
How Volvo embraced real-time 3D and shook up the auto industry- Unite Copenha...
How Volvo embraced real-time 3D and shook up the auto industry- Unite Copenha...How Volvo embraced real-time 3D and shook up the auto industry- Unite Copenha...
How Volvo embraced real-time 3D and shook up the auto industry- Unite Copenha...
 
QA your code: The new Unity Test Framework – Unite Copenhagen 2019
QA your code: The new Unity Test Framework – Unite Copenhagen 2019QA your code: The new Unity Test Framework – Unite Copenhagen 2019
QA your code: The new Unity Test Framework – Unite Copenhagen 2019
 
Engineering.com webinar: Real-time 3D and digital twins: The power of a virtu...
Engineering.com webinar: Real-time 3D and digital twins: The power of a virtu...Engineering.com webinar: Real-time 3D and digital twins: The power of a virtu...
Engineering.com webinar: Real-time 3D and digital twins: The power of a virtu...
 
Supplying scalable VR training applications with Innoactive - Unite Copenhage...
Supplying scalable VR training applications with Innoactive - Unite Copenhage...Supplying scalable VR training applications with Innoactive - Unite Copenhage...
Supplying scalable VR training applications with Innoactive - Unite Copenhage...
 
XR and real-time 3D in automotive digital marketing strategies | Visionaries ...
XR and real-time 3D in automotive digital marketing strategies | Visionaries ...XR and real-time 3D in automotive digital marketing strategies | Visionaries ...
XR and real-time 3D in automotive digital marketing strategies | Visionaries ...
 
Real-time CG animation in Unity: unpacking the Sherman project - Unite Copenh...
Real-time CG animation in Unity: unpacking the Sherman project - Unite Copenh...Real-time CG animation in Unity: unpacking the Sherman project - Unite Copenh...
Real-time CG animation in Unity: unpacking the Sherman project - Unite Copenh...
 
Creating next-gen VR and MR experiences using Varjo VR-1 and XR-1 - Unite Cop...
Creating next-gen VR and MR experiences using Varjo VR-1 and XR-1 - Unite Cop...Creating next-gen VR and MR experiences using Varjo VR-1 and XR-1 - Unite Cop...
Creating next-gen VR and MR experiences using Varjo VR-1 and XR-1 - Unite Cop...
 
What's ahead for film and animation with Unity 2020 - Unite Copenhagen 2019
What's ahead for film and animation with Unity 2020 - Unite Copenhagen 2019What's ahead for film and animation with Unity 2020 - Unite Copenhagen 2019
What's ahead for film and animation with Unity 2020 - Unite Copenhagen 2019
 
How to Improve Visual Rendering Quality in VR - Unite Copenhagen 2019
How to Improve Visual Rendering Quality in VR - Unite Copenhagen 2019How to Improve Visual Rendering Quality in VR - Unite Copenhagen 2019
How to Improve Visual Rendering Quality in VR - Unite Copenhagen 2019
 

Recently uploaded

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 

Recently uploaded (20)

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 

Unity's Evolving Best Practices

  • 1. This slide deck was presented at Unite Berlin 2018. This offline version includes numerous additional slides, cut from the original presentation for brevity and/or time. These extra slides contains more examples and data, but are not essential for understanding the presentation.
  • 2. Optimization & Best Practices: Through The Ages Ian Dundore Unity Technologies
  • 4. Spoiler Alert • Scripting Performance • Transforms • Audio • Animations
  • 9. oops. • In the specific case of String.Equals, that advice is wrong! • From a performance perspective, at least. • For all other string comparisons, it’s right! • Compare, StartsWith, EndsWith, IndexOf, etc. • Again, from a performance perspective. • (Psst! This is documented!) https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#common-string-comparison-methods-in-net
  • 11. Testing Considerations • How does the code path differ with different inputs? • What is the environment around the executing code? • Runtime • IL2CPP/Mono? .Net version? • Hardware • Pipeline depth, cache size, cache-line length • # of cores, core affinity settings on threads, throttling • What exactly is your test measuring?
  • 12. Your Test Harness Matters! Profiler.BeginSample(“Test A”); for (int i=0; i<NUM_TESTS; ++i) { DoAThing(i); } Profiler.EndSample(); int i = 0; Profiler.BeginSample(“Test B”); DoAThing(0); while (i<NUM_TESTS) { DoAThing(++i); DoAThing(++i); DoAThing(++i); // … repeat a lot … DoAThing(++i); } Profiler.EndSample(); Less Loop OverheadMore Loop Overhead
  • 13. public bool Equals(String value) { if (this == null) throw new NullReferenceException(); if (value == null) return false; if (Object.ReferenceEquals(this, value)) return true; if (this.Length != value.Length) return false; return EqualsHelper(this, value); } Mono’s String.cs (1)
  • 14. What does EqualsHelper do? • Uses unsafe code to pin strings to memory addresses. • C-style integer comparison of raw bytes of the strings. • Core is a special cache-friendly loop. • 64-bit: Step through strings with a stride of 12 bytes. while (length >= 12) { if (*(long*)a != *(long*)b) return false; if (*(long*)(a+4) != *(long*)(b+4)) return false; if (*(long*)(a+8) != *(long*)(b+8)) return false; a += 12; b += 12; length -= 12; }
  • 15. public bool Equals(String value, StringComparison comparisonType) { if (comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase) throw new ArgumentException(…); Contract.EndContractBlock(); if ((Object)this == (Object)value) { return true; } if ((Object)value == null) { return false; } Mono’s String.cs (2)
  • 16. switch (comparisonType) { case StringComparison.CurrentCulture: return (CultureInfo.CurrentCulture.CompareInfo.Compare(this, value, CompareOptions.None) == 0); case StringComparison.CurrentCultureIgnoreCase: return (CultureInfo.CurrentCulture.CompareInfo.Compare(this, value, CompareOptions.IgnoreCase) == 0); case StringComparison.InvariantCulture: return (CultureInfo.InvariantCulture.CompareInfo.Compare(this, value, CompareOptions.None) == 0); case StringComparison.InvariantCultureIgnoreCase: return (CultureInfo.InvariantCulture.CompareInfo.Compare(this, value, CompareOptions.IgnoreCase) == 0); Mono’s String.cs (3)
  • 17. case StringComparison.Ordinal: if (this.Length != value.Length) return false; return EqualsHelper(this, value); Mono’s String.cs (4)
  • 18. But wait! • For non-matching strings, length will often differ. • But for length-invariant strings, first character usually differs. • This optimization is found in CompareOrdinal, but not Equals. public static int CompareOrdinal(String strA, String strB) { if ((Object)strA == (Object)strB) return 0; if (strA == null) return -1; if (strB == null) return 1; // Most common case, first character is different. if ((strA.m_firstChar - strB.m_firstChar) != 0) return strA.m_firstChar - strB.m_firstChar; return CompareOrdinalHelper(strA, strB); }
  • 19. This is getting silly. public static int CompareOrdinal(String strA, int indexA, String strB, int indexB, int length) { if (strA == null || strB == null) { if ((Object)strA==(Object)strB) { //they're both null; return 0; } return (strA==null)? -1 : 1; //-1 if A is null, 1 if B is null. } return nativeCompareOrdinalEx(strA, indexA, strB, indexB, length); } An overload that goes almost directly to native code!
  • 20. Test Design: 4 cases • Case 1: Two identical strings. • Case 2: Two strings of random characters of same length. • Case 3: Two strings of random characters of same length. • First characters identical, to bypass check in Compare. • Case 4: Two strings of random characters, different lengths. • Comparison’s worst case is bounded by the shorter string. • Constrained range to 15-25 characters to be similar to above tests.
  • 21. Mono 3.5 Identical Content Identical Length Random Content Identical Length First Char Equal Identical Length Random Content Random Length String.Equals 2.97 1.75 1.73 1.30 String.Equals with Ordinal type 5.87 3.46 3.56 3.39 String.Compare 37.52 33.29 64.66 31.35 String.Compare with Ordinal type 6.23 3.35 3.35 3.26 CompareOrdinal 5.68 3.10 3.18 2.99 CompareOrdinal with Indices 5.53 3.30 3.42 3.95 Simple Hand-Coded 5.46 1.75 2.18 1.40 100,000 comparisons. Timings in milliseconds. Unity 2018.1.0f2, Windows Standalone, Mono 3.5, Core i7-3500K
  • 22. Mono 3.5 Identical Content Identical Length Random Content Identical Length First Char Equal Identical Length Random Content Random Length String.Equals 3.23 1.80 1.82 1.21 String.Equals with Ordinal type 3.84 2.13 2.03 1.38 String.Compare 34.72 28.70 63.03 29.74 String.Compare with Ordinal type 5.16 1.75 2.68 1.65 CompareOrdinal 4.93 1.55 2.21 1.40 CompareOrdinal with Indices 4.77 3.59 3.59 4.41 Simple Hand-Coded 4.40 1.66 1.95 1.28 100,000 comparisons. Timings in milliseconds. Unity 2018.1.0f2, Windows Standalone, Mono 4.6, Core i7-3500K
  • 23. IL2CPP Identical Content Identical Length Random Content Identical Length First Char Equal Identical Length Random Content Random Length String.Equals 2.61 1.26 1.27 0.95 String.Equals with Ordinal type 5.38 3.80 3.84 3.66 String.Compare 39.12 29.32 60.56 28.01 String.Compare with Ordinal type 4.84 3.58 3.62 3.52 CompareOrdinal 4.78 3.55 3.58 3.51 CompareOrdinal with Indices 4.93 3.71 3.72 4.17 Simple Hand-Coded 13.83 3.52 3.93 2.16 100,000 comparisons. Timings in milliseconds. Unity 2018.1.0f2, Windows Standalone, IL2CPP 3.5, Core i7-6700K
  • 24. IL2CPP Identical Content Identical Length Random Content Identical Length First Char Equal Identical Length Random Content Random Length String.Equals 2.64 1.92 1.93 0.96 String.Equals with Ordinal type 2.94 2.26 2.73 1.49 String.Compare 40.98 30.61 60.82 29.26 String.Compare with Ordinal type 3.18 1.46 2.29 1.32 CompareOrdinal 2.99 1.18 2.06 1.12 CompareOrdinal with Indices 5.56 3.93 4.08 4.41 Simple Hand-Coded 14.14 3.78 4.14 2.35 100,000 comparisons. Timings in milliseconds. Unity 2018.1.0f2, Windows Standalone, IL2CPP 4.6, Core i7-6700K
  • 27. Conclusions & more questions • String.Equals clearly wins for plain string comparison. • .NET 4.6 has improvements for String.Compare variants. • Ordinal comparisons clearly win on culture-sensitive APIs. • Use String.CompareOrdinal instead of String.Compare. • Use StringComparison.Ordinal on other String APIs. • How does this map across platforms?
  • 28. IL2CPP Identical Content Identical Length Random Content Identical Length First Char Equal Identical Length Random Content Random Length String.Equals 13.48 5.08 5.01 5.26 String.Equals with Ordinal type 25.42 19.46 19.85 14.16 String.Compare 118.80 128.69 254.30 124.81 String.Compare with Ordinal type 24.23 11.49 11.57 10.95 CompareOrdinal 23.92 11.09 11.54 10.75 CompareOrdinal with Indices 23.79 14.76 18.62 15.05 Simple Hand-Coded 58.02 12.04 21.86 8.13 100,000 comparisons. Timings in milliseconds. Unity 2018.1.0f2, iOS, IL2CPP 3.5, iPad Mini 3
  • 29. String.Equals/Random on given platform = 1 Very similar results, in this case.
  • 30. Another tip! • See a lot of time going to NullCheck in IL2CPP builds? • Disable these checks in release builds! • Works on types, methods & properties. • Code is in IL2CppSetOptionAttribute.cs, under Unity install folder [Il2CppSetOption(Option.NullChecks, false)] public bool MyEquals(String strA, String strB) { // … }
  • 31. IL2CPP Identical Content Identical Length Random Content Random Length Normal 58.02 8.13 NullCheck Disabled 53.02 7.03 100,000 comparisons. Timings in milliseconds. Unity 2018.1.0f2, iOS, IL2CPP 3.5, iPad Mini 3 Small, but helpful.
  • 32. Transforms * no, not this kind of transform
  • 34. OnTransformChanged • Internal message, broadcast each time a Transform changes • Position, rotation, scale, parent, sibling order, etc. • Tells other components to update their internal state • PhysX/Box2D, UnityUI, Renderers (AABBs), etc. • Repeated messages can cause performance problems • Use Transform.SetPositionAndRotation (5.6+)
  • 36. Enter the Dispatch • TransformChangeDispatch was first introduced in 5.4 • Other systems migrated to use it, slowly. • Renderers in 5.6 • Animators in 2017.1 • Physics in 2017.2 • RectTransforms in 2017.3 • OnTransformChanged was removed entirely in 2018.1
  • 37. How Transforms are structured • 1 TransformHierarchy structure represents a root Transform • Contains buffers tracking data of all transforms in hierarchy • TRS, indices for parents & siblings • Interest bitmask & dirty bitmask • Internal systems register interest & track state via specific bits • Physics is one bit, renderer is another bit, etc. • System walks affected parts of TransformHierarachy structure • dirtyMask |= -1 & interestMask
  • 38. When are async changes applied? • TCD keeps a list of dirty TransformHierarchy pointers • Systems request list of changed Transforms before running. • e.g. Before FixedUpdate, before rendering, before animating. • Use list to update internal system state. • TCD iterates over list of dirty TransformHierarchies. • Iterates over all Transforms to check each dirty bit.
  • 39.
  • 40. Quick Reminder • Buffer size: Transform.hierarchyCapacity • Set before mass reparenting operations! • Reparent & reposition during instantiate! • GameObject.Instantiate( prefab, parent ); • GameObject.Instantiate( prefab, parent, position, rotation );
  • 41. Split your hierarchies. • Changing any Transform marks the whole Hierarchy dirty. • Dirty hierarchies must be fully examined for change bits. • Smaller hierarchies = more granular Hierarchy tracking. • Smaller hierarchies = fewer Transforms to check. • Fewer roots = more Transforms to check for changes. • Change checks are jobified, but operate on roots.
  • 42. Extreme cases. UnparentedParented 100 Root GameObjects + 1000 empty GameObjects + 1 Cube w/ Rotation script 100,000 empty GameObjects 100 Cubes w/ Rotation script
  • 43. A welcome effect. Parented Unparented Main Thread 553 ms 32 ms Worker Threads 139 ms 14 ms 100 Rotating Cubes, 100k Empty GameObjects. iPad Mini 3. CPU time used over 10 seconds.
  • 44. This is just checking hierarchies! Parented Unparented Main Thread 1.77 ms 0.11 ms 100 Rotating Cubes, 100k Empty GameObjects. iPad Mini 3. CPU time used over 10 seconds. “PostLateUpdate.UpdateAllRenderers”
  • 45. Transforms & Physics: 2017.2+ • 2017.1/older: Physics components were synced to Transforms. • Each Transform change = expensive update of Physics scene. • 2017.2/newer: Updates can be delayed to next FixedUpdate. • Update Physics entities from set of changed Transforms. • Re-indexing computations are batched. • This could have side-effects! • Move a Collider + immediately Raycast towards it? No bueno.
  • 46. Physics.AutoSyncTransforms • When true, forces legacy behavior. • Colliders/Rigidbodies check for syncs on every Physics call. • Yes, every Raycast, Spherecast, etc. • Huge performance regression, if you’re not batching updates. • When false, uses delayed-update behavior. • Can force updates: Physics.SyncTransforms • Default value is true in 2017.2 through 2018.2 • 2018.3 is the first version where the default is false.
  • 47. void Update() { float rotAmt = 2f * Time.deltaTime; Vector3 up = Vector3.up; if (batched) { for(int i = 0; i < NUM_PARENTS; ++i) rotators[i].Rotate(up, rotAmt); for(int i = 0; i < NUM_PARENTS; ++i) Physics.Raycast(Vector3.zero, Random.insideUnitSphere); } else { for (int i = 0; i < NUM_PARENTS; ++i) { rotators[i].Rotate(up, rotAmt); Physics.Raycast(Vector3.zero, Random.insideUnitSphere); } } } A test. “Batched” “Immediate”
  • 48. Seriously, a big effect. Parented Immediate Unparented Immediate Parented Batched Unparented Batched Script 4450 ms 4270 ms 1980 ms 882 ms Physics 1410 ms 1820 ms 1840 ms 1770 ms 100 Rotating Cubes, Rigidbodies, Trigger Box Colliders. 100k Empty GameObjects. App Framerate: 30. Physics Timestep 0.04 sec. iPad Mini 3. CPU time used over 10 seconds.
  • 49. Audio
  • 50. The Basics • Unity uses FMOD internally. • Audio decoding & playback occurs on separate threads. • Unity supports a handful of codecs. • PCM • ADPCM • Vorbis • MP3
  • 51. Audio “Load Type” Setting • Decompress On Load • Decoding & file I/O happen at load time only. • Compressed In Memory • Decoding happens during playback. • Streamed • File I/O & decoding happen during playback.
  • 52. Every frame… • Unity iterates over all active Audio Sources. • Calculates distance to Listener(s). • FMOD mixes active Audio Sources (“voices”). • True volume = Volume setting * distance to listener * clip. • If the clip is compressed, FMOD must decode audio data • Chooses X loudest voices to mix together. • X = “Real Voices” audio setting.
  • 53. Everything is done in software. • Decoding & mixing are done entirely in software. • Mixing occurs on the FMOD thread. • Decoding occurs at loading time or on the FMOD thread. • All playing voices are evaluated and mixed. • Max number of voices is controlled by Audio settings.
  • 54. A trap. This voice is Muted. This voice is Active. This voice will not be heard, but the Clip must be processed.
  • 55. A warning. • AudioSystem.Update is Unity updating the AudioSources which are submitted to FMOD for playback. • Audio decoding does not show up in the Unity CPU Profiler.
  • 56. Check both places! • Decoding & mixing audio is in the details of the Audio profiler.
  • 57. Audio CPU usage by codec. 10 Voices 100 Voices 500 Voices PCM 1.5% 5.0% 5.7% ADPCM 5.2% 16.6% 11.6% MP3 13.3% 35.0% 23.3% Vorbis 12.5% 30.3% 21.2% Identical AudioClip, multiple AudioSources. MP3 & Vorbis Quality = 100.
  • 58. WTF? 10 Voices 100 Voices 500 Voices PCM 1.5% 5.0% 5.7% ADPCM 5.2% 16.6% 11.6% MP3 13.3% 35.0% 23.3% Vorbis 12.5% 30.3% 21.2% Identical AudioClip, multiple AudioSources. MP3 & Vorbis Quality = 100.
  • 60. ~Test time~ <(^^<) (>^^)> • Identical 4 minute audio clip, copied 4 times. • Once per codec under test. • Varying number of AudioSources. • Captured CPU time on main & FMOD threads • Sum of CPU time consumed over 10 seconds real-time
  • 61. Again. 10 Clips 100 Clips 500 Clips PCM 95 ms 467 ms 2040 ms ADPCM 89 ms 474 ms 2070 ms MP3 84 ms 469 ms 2030 ms Vorbis 93 ms 473 ms 1990 ms CPU time on main thread, 10 seconds real-time.
  • 62. With intensity. 10 Voices 100 Voices 500 Voices PCM 214 ms 451 ms 634 ms ADPCM 485 ms 1391 ms 1591 ms MP3 1058 ms 4061 ms 4167 ms Vorbis 1161 ms 3408 ms 3629 ms CPU time on all FMOD threads, 10 seconds real-time.
  • 63. Principles. • Avoid having many audio sources set to Mute. • Disable/Stop instead of Mute, if possible. • If you can afford the memory overhead, Decompress on Load. • Best for short clips that are frequently played. • Avoid playing lots of compressed Clips, especially on mobile.
  • 64. Or clamp the voice count. 10 Playing Clips 100 Playing Clips 500 Playing Clips 512 VV 318 ms 923 ms 2708 ms 100 VV 304 ms 905 ms 1087 ms 10 VV 315 ms 350 ms 495 ms 1 VV 173 ms 210 ms 361 ms PCM. CPU time on FMOD + Main threads, 10 seconds real-time.
  • 65. How, you ask? public void SetNumVoices(int nv) { var config = AudioSettings.GetConfiguration(); if(config.numVirtualVoices == nv) return; config.numVirtualVoices = nv; config.numRealVoices = Mathf.Clamp(config.numRealVoices, 1, config.numVirtualVoices); AudioSettings.Reset(config); } Just an example! Probably too simple for real use.
  • 67. Animator • Formerly called Mecanim. • Graph of logical states. • Blends between states. • States contain animation clips and/or blend trees. • Animator component attached to GameObject • AnimatorController referenced by Animator component.
  • 68. Playables • Technology underlying Animator & Timeline. • Generic framework for “stuff that can be played back”. • Animation clips, audio clips, video clips, etc. • Docs: https://docs.unity3d.com/Manual/Playables.html
  • 69. Animation • Unity’s original animation system. • Custom code • Not based on Playables. • Very simple: plays an animation clip. • Can crossfade, loop.
  • 71. The Test • 100 GameObjects with Animator or Animation component • Animator uses simple AnimatorController: 1 state, looping • Animation plays back 1 AnimationClip, looping
  • 72. 0 ms 10 ms 20 ms 30 ms 1 100 200 300 400 500 600 700 800 Animation Animator 100 Components, Variable Curve Count, iPad Mini 3 TimeperFrame
  • 73. How do cores affect it?
  • 74. 0 ms 1 ms 2 ms 3 ms 1 100 200 300 400 500 600 700 800 Animation Animator 100 Components, Variable Curve Count, Win10/Core i7 TimeperFrame Crossover on iPad Mini 3
  • 75. 0 ms 1 ms 2 ms 3 ms 1 100 200 300 400 500 Animation Animator 100 Curves, Variable Component Count, Win10/Core i7 TimeperFrame
  • 76. Scaling Factors • Performance is heavily dependent on curve & core count. • Fewer cores: Animation retains advantage longer. • More cores: Animator rapidly outperforms Animation. • Both systems scale linearly as number of Components rises. • “Best” system determined by target hardware vs curve count. • Use Animation for simple animations. • Use Animators for high curve counts or complex scenarios.
  • 77. 0 ms 13 ms 27 ms 40 ms 1 100 200 300 400 500 Animation Animator 100 Curves, Variable Component Count, iPad Mini 3 TimeperFrame
  • 78. What about “constant” curves? • Still interpolated at runtime. • No measurable impact on CPU usage. • Significant memory/file savings. • Example: 11kb vs. 3.7kb for 100 position curves (XYZ)
  • 80. Be careful with Layers! • The active state on each layer will be evaluated once per frame. • Layer Weight does not matter. • Weight=0? Still evaluated! • This is to ensure that state is correct. • Zero-weight layers = waste work • Use layers sparingly! (Yes, the docs are wrong.)
  • 81. The Cost of Layering 1 Layer 2 Layers 3 Layers 4 Layers 5 Layers Aggregate 1966 ms 2260 ms 2510 ms 2690 ms 2890 ms Per Frame 10.08 ms 11.77 ms 12.86 ms 14.31 ms 17.65 ms 50 x “Ellen” from 3D Gamekit. Unity 2018.1.0f2. Main Thread CPU time consumed during 10 Seconds Realtime. iPad Mini 3.
  • 83. Nope. 50 x “Ellen” from 3D Gamekit. Layers 2-5 Masked. Main Thread CPU time consumed during 10 Seconds Realtime. Unity 2018.1.0f2. iPad Mini 3. 1 Layer 2 Layers 3 Layers 4 Layers 5 Layers Unmasked 1966 ms 2260 ms 2510 ms 2690 ms 2890 ms 60/108 Masked 1992 ms 2230 ms 2530 ms 2740 ms 2920 ms
  • 84. Use the right rig! • The Humanoid rig runs IK & retargeting calculations. • The Generic rig does not. 1 Layer 2 Layers 3 Layers 4 Layers 5 Layers Generic 1966 ms 2260 ms 2510 ms 2690 ms 2890 ms Humanoid 2775 ms 3210 ms 3510 ms 3730 ms 4020 ms Identical test to previous slide, different Rig import settings.
  • 85. The pooling problem • Animators reset their state when their GameObject is disabled. • The only workaround? Disable Animator component, not GameObject. • Leads to messy side effects, like having to manage other components (e.g. Colliders/Rigidbodies) manually. • This made Animator-driven objects difficult to pool.
  • 86. There’s an API to fix it, now! • Animator.keepControllerStateOnDisable • Available in 2018.1+ • If true, Animators do not discard data buffers when their GameObject is disabled. • Awesome for pooling! • Careful of the higher memory usage of disabled Animators!