Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: build/toolchain/get_concurrent_links.py

Issue 2259503002: build: Refactor get_concurrent_links.py (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: refactor script Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 # This script computs the number of concurrent links we want to run in the build 5 # This script computs the number of concurrent links we want to run in the build
6 # as a function of machine spec. It's based on GetDefaultConcurrentLinks in GYP. 6 # as a function of machine spec. It's based on GetDefaultConcurrentLinks in GYP.
7 7
8 import optparse 8 import optparse
9 import os 9 import os
10 import re 10 import re
11 import subprocess 11 import subprocess
12 import sys 12 import sys
13 13
14 def _GetDefaultConcurrentLinks(is_lto): 14 def _GetTotalMemoryInBytes():
15 # Inherit the legacy environment variable for people that have set it in GYP.
16 pool_size = int(os.getenv('GYP_LINK_CONCURRENCY', 0))
17 if pool_size:
18 return pool_size
19
20 if sys.platform in ('win32', 'cygwin'): 15 if sys.platform in ('win32', 'cygwin'):
21 import ctypes 16 import ctypes
22 17
23 class MEMORYSTATUSEX(ctypes.Structure): 18 class MEMORYSTATUSEX(ctypes.Structure):
24 _fields_ = [ 19 _fields_ = [
25 ("dwLength", ctypes.c_ulong), 20 ("dwLength", ctypes.c_ulong),
26 ("dwMemoryLoad", ctypes.c_ulong), 21 ("dwMemoryLoad", ctypes.c_ulong),
27 ("ullTotalPhys", ctypes.c_ulonglong), 22 ("ullTotalPhys", ctypes.c_ulonglong),
28 ("ullAvailPhys", ctypes.c_ulonglong), 23 ("ullAvailPhys", ctypes.c_ulonglong),
29 ("ullTotalPageFile", ctypes.c_ulonglong), 24 ("ullTotalPageFile", ctypes.c_ulonglong),
30 ("ullAvailPageFile", ctypes.c_ulonglong), 25 ("ullAvailPageFile", ctypes.c_ulonglong),
31 ("ullTotalVirtual", ctypes.c_ulonglong), 26 ("ullTotalVirtual", ctypes.c_ulonglong),
32 ("ullAvailVirtual", ctypes.c_ulonglong), 27 ("ullAvailVirtual", ctypes.c_ulonglong),
33 ("sullAvailExtendedVirtual", ctypes.c_ulonglong), 28 ("sullAvailExtendedVirtual", ctypes.c_ulonglong),
34 ] 29 ]
35 30
36 stat = MEMORYSTATUSEX(dwLength=ctypes.sizeof(MEMORYSTATUSEX)) 31 stat = MEMORYSTATUSEX(dwLength=ctypes.sizeof(MEMORYSTATUSEX))
37 ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat)) 32 ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(stat))
38 33 return stat.ullTotalPhys
39 # VS 2015 uses 20% more working set than VS 2013 and can consume all RAM
40 # on a 64 GB machine.
41 mem_limit = max(1, stat.ullTotalPhys / (5 * (2 ** 30))) # total / 5GB
42 hard_cap = max(1, int(os.getenv('GYP_LINK_CONCURRENCY_MAX', 2**32)))
43 return min(mem_limit, hard_cap)
44 elif sys.platform.startswith('linux'): 34 elif sys.platform.startswith('linux'):
45 if os.path.exists("/proc/meminfo"): 35 if os.path.exists("/proc/meminfo"):
46 with open("/proc/meminfo") as meminfo: 36 with open("/proc/meminfo") as meminfo:
47 memtotal_re = re.compile(r'^MemTotal:\s*(\d*)\s*kB') 37 memtotal_re = re.compile(r'^MemTotal:\s*(\d*)\s*kB')
48 for line in meminfo: 38 for line in meminfo:
49 match = memtotal_re.match(line) 39 match = memtotal_re.match(line)
50 if not match: 40 if not match:
51 continue 41 continue
52 mem_total_gb = float(match.group(1)) / (2 ** 20) 42 return float(match.group(1)) * 2**10
53 # Allow 8Gb per link on Linux because Gold is quite memory hungry
54 mem_per_link_gb = 8
55 if is_lto:
56 mem_total_gb -= 10 # Reserve
57 # For LTO builds the RAM requirements are even higher
58 mem_per_link_gb = 24
59 return int(max(1, mem_total_gb / mem_per_link_gb))
60 return 1
61 elif sys.platform == 'darwin': 43 elif sys.platform == 'darwin':
62 try: 44 try:
63 avail_bytes = int(subprocess.check_output(['sysctl', '-n', 'hw.memsize'])) 45 avail_bytes = int(subprocess.check_output(['sysctl', '-n', 'hw.memsize']))
64 # A static library debug build of Chromium's unit_tests takes ~2.7GB, so
65 # 4GB per ld process allows for some more bloat.
66 return max(1, avail_bytes / (4 * (2 ** 30))) # total / 4GB
67 except Exception: 46 except Exception:
68 return 1 47 return 0
69 else: 48 # TODO(scottmg): Implement this for other platforms.
70 # TODO(scottmg): Implement this for other platforms. 49 return 0
71 return 1 50
51
52 def _GetDefaultConcurrentLinks(mem_per_link_gb, reserve_mem_gb):
53 # Inherit the legacy environment variable for people that have set it in GYP.
54 pool_size = int(os.getenv('GYP_LINK_CONCURRENCY', 0))
55 if pool_size:
56 return pool_size
57
58 mem_total_bytes = _GetTotalMemoryInBytes()
59 mem_total_bytes -= reserve_mem_gb * 2**30
brucedawson 2016/08/22 19:31:32 You probably need to check for this going negative
boliu 2016/08/22 20:49:03 Done.
60 num_concurrent_links = int(max(1, mem_total_bytes / mem_per_link_gb / 2**30))
61 hard_cap = max(1, int(os.getenv('GYP_LINK_CONCURRENCY_MAX', 2**32)))
62 return min(num_concurrent_links, hard_cap)
63
72 64
73 def main(): 65 def main():
74 parser = optparse.OptionParser() 66 parser = optparse.OptionParser()
75 parser.add_option('--lto', action="store_true", default=False, 67 parser.add_option('--mem_per_link_gb', action="store", type="int", default=8)
76 help='This is an LTO build with higher memory requirements') 68 parser.add_option('--reserve_mem_gb', action="store", type="int", default=0)
77 parser.disable_interspersed_args() 69 parser.disable_interspersed_args()
78 options, args = parser.parse_args() 70 options, args = parser.parse_args()
79 71
80 print _GetDefaultConcurrentLinks(is_lto=options.lto) 72 print _GetDefaultConcurrentLinks(options.mem_per_link_gb,
73 options.reserve_mem_gb)
81 return 0 74 return 0
82 75
83 if __name__ == '__main__': 76 if __name__ == '__main__':
84 sys.exit(main()) 77 sys.exit(main())
OLDNEW
« build/toolchain/concurrent_links.gni ('K') | « build/toolchain/concurrent_links.gni ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698