slides from gdc 2013 talk "under the hood of blizzard's internal build system"

80
UNDER THE HOOD OF BLIZZARD'S INTERNAL BUILD SYSTEM Blaine Whittle bwhittle@blizza rd.com

Upload: r-blaine-whittle

Post on 04-Jun-2015

23.646 views

Category:

Design


0 download

TRANSCRIPT

Page 1: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

UNDER THE HOOD OF BLIZZARD'S INTERNAL BUILD SYSTEM

Blaine Whittlebwhittle@blizzard

.com

Page 2: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

GAMES ARE GETTING BIGGER!

1996 1998 2000 2002 2004 2006 2008 2010 20120 GB

10 GB

20 GB

30 GB

0.5 GB

5.8 GB

10 GB

19 GB

12 GB

20 GB18 GB

32 GB

20 GB

Game install size for enUS clients

Page 3: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

SMALL-SCALE DISTRIBUTED SYSTEMS

• 1-10 Jobs

• Top down scaling

PCDebug

MacReleas

e

PCReleas

eStart End

Page 4: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Code Build Task Graph

Rendered via Graphvizsfdp layout engine

Page 5: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

LARGE-SCALE DISTRIBUTED SYSTEMS

• 10,000 – 500,000 Tasks

• Bottom up scaling

Page 6: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

File

Task

File File• Fine grained dependencies• Minimize IO

• Very lightweight tasks• High concurrency• Reattempt on error

LARGE-SCALE DISTRIBUTED SYSTEMS

Page 7: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

DistCC

XCode Distributed Builds

DMake Incredibuild

Maven

Hudson / Jenkins

Make

Ant

MPI

Google MapReduce

Distributed & Scalable

Heterogeneous

Tools

Heterogeneous

Platforms

EVALUATING EXISTING TOOLS

What we need

Page 8: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

PROBLEM REQUIREMENTS

• Use graph analysis and dataflow paradigm for maximum parallelism

• Multiplatform (hosts and build targets)

• Incorporate existing processing tools into new framework

• Design for maximum execution performance

Page 9: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

PROJECT “SANITY”

Page 10: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

DATAFLOW

• A dataflow architecture is functional programming using nodes that are stream processors

• In our dataflow pattern, the nodes are tasks that read immutable files and produce new files and new tasks

Page 11: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Foo.exe

IMMUTABLE FILES

Foo.exe

Sign Task

Foo.unsigned.exe• During a Sanity build, file paths can only be written to once

• Tasks that normally modify a file in place become a copy on write

• Unlimited directories and filenames

Page 12: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

FRAMEWORK

• Task = smallest unit of schedulable work

• Metatask = a task that may define additional tasks • Allows us to reason about the remaining work• If only tasks remain, we know our dependency graph

is complete

• Rule = procedurally generates tasks based on file name patterns• Map Rule = 1 file 1 task• Reduce Rule = N files 1 task

Page 13: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Each task must implement two functions

• Parse• Execute

TASK API

Page 14: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

File C

Task Foo

File A File B• Parse

• Takes an opaque data structure called a task line

• ReturnsList of input filesList of output files

• Pure function / no side effects

TASK API - PARSE

Page 15: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

File C

Task Foo

File A File B

TASK API - PARSE

File C

Task Bar

File D

Task Foo

Task Bar

Task dependencies are

implicit

Page 16: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Code Build Task Graph

Task

Meta Task

Page 17: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Code Build File & Task Graph

Task

Meta Task

Artifact File

Source File

Page 18: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Parse functions may not directly open or read files

• However Parse may return a set of closures for transforming file contents into a list of additional input file paths

TASK API - PARSE

File C

Task Foo

File BFile A

Page 19: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Compile

FILE FILE DEPENDENCIES

File.hFile.cp

p

Page 20: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Compile

FILE FILE DEPENDENCIES

File.h

Foo.hInclud

e.h

File dependencies can be cyclic

File.cpp

Page 21: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

File C

Task Foo

File B• Execute

• Does the actual work, i.e. reads input files and creates output files

• Returns either• Result (Success / Failure)• A new set of task lines

(Metatasks)

All state is passed via task lines or files

TASK API - EXECUTE

File A

Page 22: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

EXTENDED EXAMPLE

3 Metatasks• 1 solution file• 2 project files

26 Tasks• 23 compile tasks• 2 link tasks (1 lib)• 1resource compile task

Page 23: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

.SANITY FILE

[ {tasks, [

{vs_solution, "IcePaq/Icepaq.sln", "Release|Win32"} ]}, {deliverables,[

"IcePaq/win32_release/Icepaq.exe" ]}, {deploy, [

{location, {smb, "//someserver/someshare“}} ]}, {vfs, [

{"/",{rep, svn, "http://svn-repository/trunk/", head}} ]}].

Page 24: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

SOLUTION TASK PARSEParse Result

Dependency Graph

Task Line

Input Files

Output Files

Icepaq.sln{vs_solution,"IcePaq/Icepaq.sln","Release|Win32"}

Blocked Task or File

Evaluated Task or File

Unevaluated File

Page 25: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

SOLUTION TASK EXECUTE

{vs_solution,"IcePaq/Icepaq.sln","Release|Win32"}

Execute Result

{vc_project,["IcePaq/ConsoleMopaq.vcproj"], "IcePaq/Release/Mopaq.lib",

"Release|Win32", [{solution_dir,"IcePaq/"}]}

{vc_project,[“IcePaq/Icepaq.vcproj"], "IcePaq/Release/Icepaq.exe",

"Release|Win32", [{solution_dir,"IcePaq/"}]}

Task Line

Page 26: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

PROJECT TASK PARSEParse Result

{vc_project,[“IcePaq/Icepaq.vcproj"], "IcePaq/Release/Icepaq.exe",

"Release|Win32", [{solution_dir,"IcePaq/"}]}

Task Line

Input Files

Output Files

Icepaq.vcproj

Icepaq.exe

Page 27: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

PROJECT TASK PARSEParse Result

{vc_project,["IcePaq/ConsoleMopaq.vcproj"], "IcePaq/Release/Mopaq.lib",

"Release|Win32", [{solution_dir,"IcePaq/"}]}

Task Line

Input Files

Output Files

ConsoleMopaq.vcproj

Mopaq.lib

Dependency Graph

Page 28: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

PROJECT TASK EXECUTE

{vc_project,["IcePaq/ConsoleMopaq.vcproj"], "IcePaq/Release/Mopaq.lib",

"Release|Win32", [{solution_dir,"IcePaq/"}]}

Execute Result

{vc8_compile,"Contrib/Zlib/Contrib_zlib.c", ["IcePaq/Release/Contrib_zlib.obj"], [{vcproj,"IcePaq/ConsoleMopaq.vcproj"}, {search_paths, "Contrib/Zlib", "Tools/Mopaq/IcePaq”, "BlizzardCore/Include", "BlizzardCore/Source/Packages”, "BlizzardCore/Source/Packages/Mopaq”, "Shared","Contrib"]}, {platform,"Win32"}, {workdir, "IcePaq"}]}, …

Task Line

Page 29: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

COMPILE TASK PARSEParse Result

{vc8_compile,"Contrib/Zlib/Contrib_zlib.c", ["IcePaq/Release/Contrib_zlib.obj"], [{vcproj,"IcePaq/ConsoleMopaq.vcproj"}, {search_paths, "Contrib/Zlib", "Tools/Mopaq/IcePaq”, "BlizzardCore/Include", "BlizzardCore/Source/Packages”, "BlizzardCore/Source/Packages/Mopaq”, "Shared","Contrib"]}, {platform,"Win32"}, {workdir, "IcePaq"}]},

Task Line

Input Files

Output Files

Contrib_zlib.c

Contrib_zlib.obj

Repeated for other tasks in this project

Page 30: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Blocked Task or File

Evaluated Task or File

Unevaluated File

Page 31: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

2nd Project task complete

Blocked Task or File

Evaluated Task or File

Unevaluated File

Page 32: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

1st compile task complete

Include files for this .CPP file

Blocked Task or File

Evaluated Task or File

Unevaluated File

Page 33: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Our focus

2nd and 3rd compile tasks complete

Even more include files

Blocked Task or File

Evaluated Task or File

Unevaluated File

Page 34: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

4th compile task complete

Blocked Task or File

Evaluated Task or File

Unevaluated File

Page 35: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Blocked Task or File

Evaluated Task or File

Unevaluated File

Page 36: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Linker can now run

Blocked Task or File

Evaluated Task or File

Unevaluated File

Page 37: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Build is complete!

Blocked Task or File

Evaluated Task or File

Unevaluated File

Map

Reduce

Page 38: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

USE CASES

• Code compilation• Asset transformation• Texture mipmap reduction• Path map generation• Shader compilation• Archive creation• Patch generation

Page 39: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Pathmap Generation Task Graph

Task

Meta Task

Page 40: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Pathmap Generation File & Task Graph

Task

Meta Task

Artifact File

Source File

Page 41: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Shader Compilation File & Task Graph

Task

Meta Task

Artifact File

Source File

Page 42: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

LESSONS LEARNED

• Memory footprint issues related to large graphs

• Language difficulties with Erlang• Mnesia (built in distributed DB)• String handling performance

• Unrealized VS 2008 integration• Replacing an 8 hour build process

required many test runs of both the old and new systems

Page 43: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

IMPLEMENTATION

Page 44: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

FILE CACHE MANAGEMENT

Traditional repo checkout system is problematic

• Often fetches unused files

• Doesn’t scale• Across branches• Across build machines

• File system tree includes build state that needs cleaning or repairing

Page 45: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

FILE CACHE MANAGEMENT

• Non-traditional repo interface

• Repo plugin driver architecture• Simple API

• Similar to GIT’s internals• Content addressable

cache• Managed working directory

via hard links to the local cache

• Ability to map repo paths to build paths

/ Source/ Art/

P4 Repo

Svn Repo

Logical File System Physical File Systems

Virtual File System

Page 46: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Perforce Repo

LocalCache

Work Dir

Task

Task Task

LocalCache

Work Dir

Task

Task

LocalCache

Work Dir

Task

Subversion Repo

• Files not in cache are fetched (i.e. lazy)

• Files can be fetched from other machines

• Content addressable cache (md5)

• Hard linked to the working directory

Machine A Machine B Machine C

Page 47: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Machine A Machine B Machine C

Perforce Repo

LocalCache

Work Dir

Task

Task Task

LocalCache

Work Dir

Task

Task

LocalCache

Work Dir

Task

Subversion Repo

SMB Deploy Share

• Tasks write new files to the working dir

• Output files are hashed and hard linked to local cache• Immutability

enforced via ACL• Async deploy build

results

Page 48: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

LocalCache

Work Dir

LocalCache

Work Dir

LocalCache

Work Dir

• Transient working directory

• Working directory can be recreated• Pause/Resume

Build• Debugging

Machine A Machine B Machine C

Page 49: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Tracks task to task dependencies

• When a task is no longer blocked the task is dispatched to the build queue

Builder

Build Queue

Node Queue

Runner

Runner

Runner

Node Queue

Runner

Runner

Node Queue

Runner

Runner

Runner

Machine A Machine B Machine C

BUILDER

Page 50: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Acts as a task router for the cluster

• Routes groups of tasks to specific machines based on a consistent hash of the parent task line

BUILD QUEUEBuilder

Build Queue

Runner

Runner

Runner

Runner

Runner

Runner

Runner

Runner

Machine A Machine B Machine C

Node Queue

Node Queue

Node Queue

Page 51: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Minimizes key map changes when nodes are added or removed

• Keys and machines are mapped to slots

CONSISTENT HASHING

Slots

A B DMachines

Hash Keys

Page 52: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• When we add a node only keys / nodes (avg) are remapped

CONSISTENT HASHING

A B C DMachines

Slots

Hash Keys

Page 53: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Each machine manages its own task queue

• Allows low latency transitions to new tasks

• Max runners = CPU cores

NODE QUEUEBuilder

Build Queue

Runner

Runner

Runner

Runner

Runner

Runner

Runner

Runner

Machine A Machine B Machine C

Node Queue

Node Queue

Node Queue

Page 54: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Exists for the lifetime of a single task

• Sets up the working directory and fetches any required files

• Verifies and hashes output files

Builder

Build Queue

Runner

Runner

Runner

Runner

Runner

Runner

Runner

Runner

Machine A Machine B Machine C

RUNNER

Node Queue

Node Queue

Node Queue

Page 55: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

LOAD BALANCING

Cache & Machine Affinity

Fault ToleranceLoad BalancingFaster but brittleFlexible but slower

Page 56: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

THREAD WORK STEALING

CPU Core 1

Thread Queue

CPU Core 2

Thread Queue

CPU Core 3

Thread Queue

CPU Core 4

Thread Queue

Page 57: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Each machine executes tasks from its local queue

• Task stealing occurs between neighbors in a loop

• Build queue process manages the loop

TASK STEALING

Queued Tasks

Executing Tasks

Build Queue

Machine A

Machine C

Machine B

Machine D

Machine F Machine E

Page 58: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Machine runs low on tasks event

• Asynchronous steal work requests are sent to both neighbors

• If a request can’t be fulfilled, its forwarded along the loop

TASK STEALING

?Steal work

request

Steal workrequest

Forwarded steal work

request

Machine A

Machine C

Machine B

Machine D

Machine F Machine E

Page 59: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Response is sent directly to the original machine

• Build queue is notified of the ownership change

Steal workresponse

!

! TASK STEALING

Machine A

Machine C

Machine B

Machine D

Machine F Machine E

Page 60: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Smaller groups were all run on a single node

Largest groups ran on at least two nodes

Node color represents the machine that executed the task

Page 61: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

• Tasks are loosely bound to a machine based on the hash of its parent task

• Likelihood of executing a specific task is based on the distance along the loop

SOFT CACHE AFFINITY

Default node for Task Foo

Machine A

Machine C

Machine B

Machine D

Machine F Machine E

01

12

3 2

Page 62: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

HARDWARE SCALING

4 6 80

1

2

3

4

5

6

30.8 mins

24.4 mins 22.2 mins

22.5 mins16.2 mins

13.5 mins

UncachedLinearCached

Builds / Hour

Cluster Size

SC2 Data Build

Page 63: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

HARDWARE SCALING

1 2 3 4 5 6 7 80

2

4

6

8

10

58.7 mins

25.4 mins

17.4 mins

14.5 mins

11.0 mins

9.1 mins13.3 mins

9.6 mins

8.0 mins

UncachedLinearCached

SC2 Shader Generation

Builds / Hour

Cluster Size

Page 64: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

I’m a PC Task

I’m a Mac Task

I’m a Task that

goes both ways

I’m a Mac

I’m a PC

HETEROGENEOUS LOAD BALANCING

Page 65: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

TASK MACHINE DEPENDENCIES

• Tasks have specific machine requirements• Visual Studio 2008• Perl• XCode 3.2• CUDA • Win64

Page 66: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

TASK MACHINE MATRIX

Machine A

Machine B

Machine C

Machine D

Task 1 X X

Task 2 X X

Task 3 X X

Task 4 X X X

Task 5 X X X X

Task 6 X X X X

Page 67: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

LOOP ORDERING

• Consistent ordering

• Avoid gaps between “colors”

• Gaps impede work stealing

Machine A

Machine B

Machine D

Machine C

Page 68: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

LOOP ORDERING

• Similar to traveling salesman problem (NP hard)

• Order the machines from the most constrained colors to the least

Machine A

Machine B

Machine D

Machine C

Page 69: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

OPTIMAL ORDERING

Group by• Blue (2

Machines)• Red (2 Machines)• White (3

Machines)• Yellow (All

machines)

Machine A

Machine B

Machine D

Machine C

Page 70: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

OPTIMAL ORDERING

Machine B

Machine A

Machine D

Machine C

Swapped positions Group by

• Blue (2 Machines)

• Red (2 Machines)• White (3

Machines)• Yellow (All

machines)

Page 71: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

WE'RE HIRING

Page 72: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Q&Abwhittle@blizzard

.com

Page 73: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

UNDER THE HOOD OF BLIZZARD'S INTERNAL

BUILD SYSTEM

Page 74: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

TOOL TIPS AND TRICKS

• No GUI dialogs or windowed error messages

• If an error occurs return a non zero result code

• If an error occurs because of a malformed input file, print out the filename and the error

Page 75: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

TOOL TIPS AND TRICKS

• Avoid using exclusive read when opening input files

• Avoid using write access when opening input files that you don’t actually write to

• Avoid editing files in place, or at the very least provide command line switches to explicitly name both the input and output files

Page 76: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

TOOL TIPS AND TRICKS

• Don't have fixed / hardcoded file paths (especially absolute file paths). All filenames should be assignable via command line switches

• If the tool does any type of batch processing of files, ensure that individual steps can be executed independently via additional command line switches

Page 77: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

TOOL TIPS AND TRICKS

• Embed paths in data, not code (write out a text file describing the paths)

• Minimize dependencies

Page 78: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

ShaderCompil

e

Data Build

ShaderCompil

e

ShaderCompil

e

• Wait for data build to complete

• Split shader compilation into 5 batches based on graphics quality• Copy entire game (all

locales)• For each model in game

generate shader pair for each unique shader key

• Merge shader caches

SHADER COMPILE (PREVIOUS)

ShaderMerge

15 mins

45 mins

2 mins

Page 79: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

Emit Keys

EmitKeys

Emit Keys

• Generate model lists• Partition into 100 bins

• For each bin and graphics setting, loop over models and emit shader keys • Assets automatically

fetched if needed• New file format for keys

• Merge and dedup shader keys

SHADER COMPILE (SANITY)

Merge Keys

5 secs

1 min

5 secs

EmitModel Lists

Page 80: Slides from GDC 2013 talk "Under the hood of Blizzard's Internal build system"

ShaderCompil

e

ShaderCompil

e

ShaderCompil

e

• Partition keys into N bins (2,000)

• For each key bin generate shader pair from keys

• Merge shader caches via two layers • sqrt(N) = 45 caches per

merge = 46 merge tasks

SHADER COMPILE (SANITY)

Merge Shader

s

3 secs

10 mins

15 secs

Partition Keys