[Build] Add parallel PPC test generation

Utilizes `multiprocessing` to allow for multiple power-pc assembly tests
to be generated in parallel.

Some results on my i9-11900k(8c/16t):

Before:
```
Measure-Command {.\xb gentests}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 11
Milliseconds      : 200
Ticks             : 112007585
TotalDays         : 0.000129638408564815
TotalHours        : 0.00311132180555556
TotalMinutes      : 0.186679308333333
TotalSeconds      : 11.2007585
TotalMilliseconds : 11200.7585
```

After:
```
Measure-Command {.\xb gentests}

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 5
Milliseconds      : 426
Ticks             : 54265895
TotalDays         : 6.28077488425926E-05
TotalHours        : 0.00150738597222222
TotalMinutes      : 0.0904431583333333
TotalSeconds      : 5.4265895
TotalMilliseconds : 5426.5895
```

This is an over **x2** speedup!
This commit is contained in:
Wunkolo 2023-02-05 15:14:48 -08:00 committed by Rick Gibbed
parent 4a2f4d9cfe
commit f357f26eae

View file

@ -8,6 +8,8 @@ Run with --help or no arguments for possible commands.
"""
from __future__ import print_function
from datetime import datetime
from multiprocessing import Pool
from functools import partial
import argparse
import json
import os
@ -1206,37 +1208,14 @@ class GenTestsCommand(Command):
''',
*args, **kwargs)
def execute(self, args, pass_args, cwd):
print('Generating test binaries...')
print('')
binutils_path = os.path.join('third_party', 'binutils-ppc-cygwin')
ppc_as = os.path.join(binutils_path, 'powerpc-none-elf-as')
ppc_ld = os.path.join(binutils_path, 'powerpc-none-elf-ld')
ppc_objdump = os.path.join(binutils_path, 'powerpc-none-elf-objdump')
ppc_nm = os.path.join(binutils_path, 'powerpc-none-elf-nm')
test_src = os.path.join('src', 'xenia', 'cpu', 'ppc', 'testing')
test_bin = os.path.join(test_src, 'bin')
# Ensure the test output path exists.
if not os.path.exists(test_bin):
os.mkdir(test_bin)
src_files = [os.path.join(root, name)
for root, dirs, files in os.walk('src')
for name in files
if (name.startswith('instr_') or name.startswith('seq_'))
and name.endswith(('.s'))]
def process_src_file(test_bin, ppc_as, ppc_objdump, ppc_ld, ppc_nm, src_file):
print('- %s' % src_file)
def make_unix_path(p):
"""Forces a unix path separator style, as required by binutils.
"""
return p.replace(os.sep, '/')
any_errors = False
for src_file in src_files:
print('- %s' % src_file)
src_name = os.path.splitext(os.path.basename(src_file))[0]
obj_file = os.path.join(test_bin, src_name) + '.o'
shell_call([
@ -1285,6 +1264,36 @@ class GenTestsCommand(Command):
make_unix_path(obj_file),
], stdout_path=os.path.join(test_bin, src_name) + '.map')
def execute(self, args, pass_args, cwd):
print('Generating test binaries...')
print('')
binutils_path = os.path.join('third_party', 'binutils-ppc-cygwin')
ppc_as = os.path.join(binutils_path, 'powerpc-none-elf-as')
ppc_ld = os.path.join(binutils_path, 'powerpc-none-elf-ld')
ppc_objdump = os.path.join(binutils_path, 'powerpc-none-elf-objdump')
ppc_nm = os.path.join(binutils_path, 'powerpc-none-elf-nm')
test_src = os.path.join('src', 'xenia', 'cpu', 'ppc', 'testing')
test_bin = os.path.join(test_src, 'bin')
# Ensure the test output path exists.
if not os.path.exists(test_bin):
os.mkdir(test_bin)
src_files = [os.path.join(root, name)
for root, dirs, files in os.walk('src')
for name in files
if (name.startswith('instr_') or name.startswith('seq_'))
and name.endswith(('.s'))]
any_errors = False
pool_func = partial(GenTestsCommand.process_src_file, test_bin, ppc_as, ppc_objdump, ppc_ld, ppc_nm)
with Pool() as pool:
pool.map(pool_func, src_files)
if any_errors:
print('ERROR: failed to build one or more tests.')
return 1