Path: blob/main/test/benchmark/benchmark_sse.py
6173 views
#!/usr/bin/env python31# Copyright 2020 The Emscripten Authors. All rights reserved.2# Emscripten is available under two separate licenses, the MIT license and the3# University of Illinois/NCSA Open Source License. Both these licenses can be4# found in the LICENSE file.56import json7import os8import re9import subprocess10import sys1112__scriptdir__ = os.path.dirname(os.path.abspath(__file__))13__testdir__ = os.path.dirname(os.path.dirname(__file__))14__rootpath__ = os.path.dirname(__testdir__)15print(__rootpath__)16sys.path.insert(0, __rootpath__)17sys.path.insert(0, __testdir__)1819import clang_native20from common import EMRUN, test_file2122from tools.config import V8_ENGINE23from tools.shared import CLANG_CXX, EMCC24from tools.utils import WINDOWS, run_process2526# System info27system_info = subprocess.check_output([EMRUN, '--system_info'], stderr=subprocess.STDOUT, text=True)2829# Native info30native_info = subprocess.check_output(['clang', '-v'], stderr=subprocess.STDOUT, text=True)3132# Emscripten info33emscripten_info = subprocess.check_output([EMCC, '-v'], stderr=subprocess.STDOUT, text=True)343536def run_benchmark(benchmark_file, results_file, build_args):37out_dir = os.path.join(__rootpath__, 'out')38results_file = os.path.join(out_dir, results_file)39# Run native build40out_file = os.path.join(out_dir, 'benchmark_sse_native')41if WINDOWS:42out_file += '.exe'43cmd = [CLANG_CXX] + clang_native.get_clang_native_args() + [benchmark_file, '-O3', '-o', out_file]44print('Building native version of the benchmark:')45print(' '.join(cmd))46run_process(cmd, env=clang_native.get_clang_native_env())4748native_results = subprocess.check_output(out_file)49print('native_results', native_results)5051# Run emscripten build52out_file = os.path.join(out_dir, 'benchmark_sse_html.js')53cmd = [EMCC, benchmark_file, '-sENVIRONMENT=web,shell,node', '-msimd128', '-O3', '-sTOTAL_MEMORY=536870912', '-o', out_file] + build_args54print('Building Emscripten version of the benchmark:')55print(' '.join(cmd))56run_process(cmd)5758cmd = V8_ENGINE + [os.path.basename(out_file)]59print(' '.join(cmd))60wasm_results = subprocess.check_output(cmd, cwd=out_dir, text=True)6162print('wasm_results', wasm_results)6364def strip_comments(text):65return re.sub(r'//.*?\n|/\*.*?\*/', '', text, flags=re.S) # noqa6667benchmark_results = strip_comments(wasm_results)68print('stripped', benchmark_results)6970# Strip out unwanted print output.71benchmark_results = benchmark_results[benchmark_results.find('{'):].strip()72if '*************************' in benchmark_results:73benchmark_results = benchmark_results[:benchmark_results.find('*************************')].strip()7475print(benchmark_results)7677native_results = json.loads(native_results)78benchmark_results = benchmark_results[benchmark_results.index('{'):benchmark_results.rindex('}') + 1]79wasm_results = json.loads(benchmark_results)8081# native_workload = native_results['workload']82# html_workload = wasm_results['workload']8384html = '''<html><head></head><body><h1>SSE JavaScript Benchmark</h1>85<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>86<script src="https://code.highcharts.com/highcharts.js"></script>87<script src="https://code.highcharts.com/modules/exporting.js"></script><b>System Info:</b><br/>88''' + system_info.replace('\n', '<br/>') + '''89<b>Native Clang Compiler:</b><br/>90''' + native_info.replace('\n', '<br/>') + '''91<b>Emscripten Compiler:</b><br/>92''' + emscripten_info.replace('\n', '<br/>')9394charts_native = {}95charts_html = {}96for result in native_results['results']:97ch = result['chart']98if ch not in charts_native:99charts_native[ch] = []100charts_native[ch] += [result]101for result in wasm_results['results']:102ch = result['chart']103if ch not in charts_html:104charts_html[ch] = []105charts_html[ch] += [result]106107def find_result_in_category(results, category):108for result in results:109if result['category'] == category:110return result111return None112113def format_comparison(a, b):114if a < b and a != 0:115return "<span style='color:green;font-weight:bold;'> {:10.2f}".format(b / a) + 'x FASTER</span>'116elif b != 0:117return "<span style='color:red;font-weight:bold;'> {:10.2f}".format(a / b) + 'x SLOWER</span>'118else:119return "<span style='color:red;font-weight:bold;'> NaN </span>"120121chartNumber = 0122123total_time_native_scalar = 0124total_time_native_simd = 0125total_time_html_scalar = 0126total_time_html_simd = 0127128for chart_name, chart_native_results in charts_native.items():129# Extract data for each chart.130categories = []131nativeScalarResults = []132nativeSimdResults = []133htmlScalarResults = []134htmlSimdResults = []135native_results = chart_native_results136wasm_results = charts_html[chart_name]137textual_results_native = '<p>'138textual_results_html = '<p>'139textual_results_html2 = '<p>'140textual_results_html3 = '<p>'141for result in native_results:142categories += ["'" + result['category'] + "'"]143nsc = result['scalar']144nsi = result['simd']145nativeScalarResults += [str(nsc)]146nativeSimdResults += [str(nsi)]147html_result = find_result_in_category(wasm_results, result['category'])148textual_results_native += 'Native ' + result['category'] + ': ' + "{:10.4f}".format(nsc) + 'ns -> ' + "{:10.4f}".format(nsi) + 'ns. '149textual_results_native += 'Native SSE is ' + format_comparison(nsi, nsc) + ' than native scalar. <br />'150151if html_result is not None:152hsc = html_result['scalar']153htmlScalarResults += [str(hsc)]154hsi = html_result['simd']155htmlSimdResults += [str(hsi)]156textual_results_html += 'JS ' + result['category'] + ': ' + "{:10.4f}".format(hsc) + 'ns -> ' + "{:10.4f}".format(hsi) + 'ns. '157textual_results_html += 'JS SSE is ' + format_comparison(hsi, hsc) + ' than JS scalar. <br />'158textual_results_html2 += 'JS ' + result['category'] + ': JS scalar is ' + format_comparison(hsc, nsc) + ' than native scalar. <br />'159textual_results_html3 += 'JS ' + result['category'] + ': JS SSE is ' + format_comparison(hsi, nsi) + ' than native SSE. <br />'160total_time_native_scalar += nsc161total_time_native_simd += nsi162total_time_html_scalar += hsc163total_time_html_simd += hsi164else:165htmlScalarResults += [str(-1)]166htmlSimdResults += [str(-1)]167168chartNumber += 1169html += '<div id="chart' + str(chartNumber) + '" style="width:100%; height:400px; margin-top: 100px;"></div>'170html += '''<script>$(function () {171$('#chart''' + str(chartNumber) + '''').highcharts({172chart: {173type: 'column'174},175title: {176text: "''' + chart_name + '''"177},178subtitle: {179text: 'Time per operation in nanoseconds'180},181xAxis: {182categories: [''' + ','.join(categories) + '''183]184},185yAxis: {186min: 0,187title: {188text: 'Time (nanoseconds)'189}190},191tooltip: {192headerFormat: '<span style="font-size:10px">{point.key}</span><table>',193pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +194'<td style="padding:0"><b>{point.y:.3f} ns</b></td></tr>',195footerFormat: '</table>',196shared: true,197useHTML: true198},199plotOptions: {200column: {201pointPadding: 0.2,202borderWidth: 0203}204},205series: [{206name: 'Native scalar',207data: [''' + ','.join(nativeScalarResults) + ''']208209}, {210name: 'Native SSE',211data: [''' + ','.join(nativeSimdResults) + ''']212213}, {214name: 'JS scalar',215data: [''' + ','.join(htmlScalarResults) + ''']216217}, {218name: 'JS SSE',219data: [''' + ','.join(htmlSimdResults) + ''']220221}]222});223});</script>''' + '<table><tr><td>' + textual_results_native + '</td><td>' + textual_results_html + '</td></tr><tr><td>' + textual_results_html2 + '</td><td>' + textual_results_html3 + '</td></tr></table>'224225# Final overall score226227html += '<div id="overallscore" style="width:100%; height:400px; margin-top: 100px;"></div>'228html += '''<script>$(function () {229$('#overallscore').highcharts({230chart: {231type: 'column'232},233title: {234text: "Overall Execution Time"235},236xAxis: {237categories: ['Total time normalized to native']238},239yAxis: {240min: 0,241title: {242text: 'Relative time'243}244},245tooltip: {246headerFormat: '<span style="font-size:10px">{point.key}</span><table>',247pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +248'<td style="padding:0"><b>{point.y:.3f}x</b></td></tr>',249footerFormat: '</table>',250shared: true,251useHTML: true252},253plotOptions: {254column: {255pointPadding: 0.2,256borderWidth: 0257}258},259series: [{260name: 'Native scalar',261data: [''' + str(1.0) + ''']262263}, {264name: 'Native SSE',265data: [''' + (str(total_time_native_simd / total_time_native_scalar) if total_time_native_scalar != 0 else 'N/A') + ''']266267}, {268name: 'JS scalar',269data: [''' + (str(total_time_html_scalar / total_time_native_scalar) if total_time_native_scalar != 0 else 'N/A') + ''']270271}, {272name: 'JS SSE',273data: [''' + (str(total_time_html_simd / total_time_native_scalar) if total_time_native_scalar != 0 else 'N/A') + ''']274275}]276});277});</script>'''278279html += '</body></html>'280281open(results_file, 'w').write(html)282print('Wrote ' + str(len(html)) + ' bytes to file ' + results_file + '.')283284285if __name__ == '__main__':286suite = sys.argv[1].lower() if len(sys.argv) == 2 else None287if suite in ['sse', 'sse1']:288run_benchmark(test_file('benchmark/benchmark_sse1.cpp'), 'results_sse1.html', ['-msse'])289elif suite == 'sse2':290run_benchmark(test_file('benchmark/benchmark_sse2.cpp'), 'results_sse2.html', ['-msse2'])291elif suite == 'sse3':292run_benchmark(test_file('benchmark/benchmark_sse3.cpp'), 'results_sse3.html', ['-msse3'])293elif suite == 'ssse3':294run_benchmark(test_file('benchmark/benchmark_ssse3.cpp'), 'results_ssse3.html', ['-mssse3'])295else:296raise Exception('Usage: python test/benchmark/benchmark_sse.py sse1|sse2|sse3')297298299