Path: blob/main/test/benchmark/benchmark_sse.py
4133 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 shutil10import sys11import tempfile12from subprocess import Popen1314__rootpath__ = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))15sys.path.insert(0, __rootpath__)1617from tools.shared import WINDOWS, CLANG_CXX, EMCC, PIPE18from tools.shared import run_process19from tools.config import V8_ENGINE20from common import EMRUN, test_file21import clang_native2223temp_dir = tempfile.mkdtemp()2425# System info26system_info = Popen([EMRUN, '--system_info'], stdout=PIPE, stderr=PIPE).communicate()2728# Native info29native_info = Popen(['clang', '-v'], stdout=PIPE, stderr=PIPE).communicate()3031# Emscripten info32emscripten_info = Popen([EMCC, '-v'], stdout=PIPE, stderr=PIPE).communicate()333435def run_benchmark(benchmark_file, results_file, build_args):36# Run native build37out_file = os.path.join(temp_dir, 'benchmark_sse_native')38if WINDOWS:39out_file += '.exe'40cmd = [CLANG_CXX] + clang_native.get_clang_native_args() + [benchmark_file, '-O3', '-o', out_file]41print('Building native version of the benchmark:')42print(' '.join(cmd))43run_process(cmd, env=clang_native.get_clang_native_env())4445native_results = Popen([out_file], stdout=PIPE, stderr=PIPE).communicate()46print(native_results[0])4748# Run emscripten build49out_file = os.path.join(temp_dir, 'benchmark_sse_html.js')50cmd = [EMCC, benchmark_file, '-O3', '-sTOTAL_MEMORY=536870912', '-o', out_file] + build_args51print('Building Emscripten version of the benchmark:')52print(' '.join(cmd))53run_process(cmd)5455cmd = V8_ENGINE + ['--experimental-wasm-simd', os.path.basename(out_file)]56print(' '.join(cmd))57old_dir = os.getcwd()58os.chdir(os.path.dirname(out_file))59wasm_results = Popen(cmd, stdout=PIPE, stderr=PIPE).communicate()60os.chdir(old_dir)6162if not wasm_results:63raise Exception('Unable to run benchmark in V8!')6465if not wasm_results[0].strip():66print(wasm_results[1])67sys.exit(1)6869print(wasm_results[0])7071def strip_comments(text):72return re.sub('//.*?\n|/\*.*?\*/', '', text, re.S) # noqa7374benchmark_results = strip_comments(wasm_results[0])7576# Strip out unwanted print output.77benchmark_results = benchmark_results[benchmark_results.find('{'):].strip()78if '*************************' in benchmark_results:79benchmark_results = benchmark_results[:benchmark_results.find('*************************')].strip()8081print(benchmark_results)8283shutil.rmtree(temp_dir)8485native_results = json.loads(native_results[0])86benchmark_results = benchmark_results[benchmark_results.index('{'):benchmark_results.rindex('}') + 1]87wasm_results = json.loads(benchmark_results)8889# native_workload = native_results['workload']90# html_workload = wasm_results['workload']9192html = '''<html><head></head><body><h1>SSE JavaScript Benchmark</h1>93<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>94<script src="https://code.highcharts.com/highcharts.js"></script>95<script src="https://code.highcharts.com/modules/exporting.js"></script><b>System Info:</b><br/>96''' + system_info[0].replace('\n', '<br/>') + '''97<b>Native Clang Compiler:</b><br/>98''' + native_info[1].replace('\n', '<br/>') + '''99<b>Emscripten Compiler:</b><br/>100''' + emscripten_info[0].replace('\n', '<br/>')101102charts_native = {}103charts_html = {}104for result in native_results['results']:105ch = result['chart']106if ch not in charts_native:107charts_native[ch] = []108charts_native[ch] += [result]109for result in wasm_results['results']:110ch = result['chart']111if ch not in charts_html:112charts_html[ch] = []113charts_html[ch] += [result]114115def find_result_in_category(results, category):116for result in results:117if result['category'] == category:118return result119return None120121def format_comparison(a, b):122if a < b and a != 0:123return "<span style='color:green;font-weight:bold;'> {:10.2f}".format(b / a) + 'x FASTER</span>'124elif b != 0:125return "<span style='color:red;font-weight:bold;'> {:10.2f}".format(a / b) + 'x SLOWER</span>'126else:127return "<span style='color:red;font-weight:bold;'> NaN </span>"128129chartNumber = 0130131total_time_native_scalar = 0132total_time_native_simd = 0133total_time_html_scalar = 0134total_time_html_simd = 0135136for chart_name, chart_native_results in charts_native.items():137# Extract data for each chart.138categories = []139nativeScalarResults = []140nativeSimdResults = []141htmlScalarResults = []142htmlSimdResults = []143native_results = chart_native_results144wasm_results = charts_html[chart_name]145textual_results_native = '<p>'146textual_results_html = '<p>'147textual_results_html2 = '<p>'148textual_results_html3 = '<p>'149for result in native_results:150categories += ["'" + result['category'] + "'"]151nsc = result['scalar']152nsi = result['simd']153nativeScalarResults += [str(nsc)]154nativeSimdResults += [str(nsi)]155html_result = find_result_in_category(wasm_results, result['category'])156textual_results_native += 'Native ' + result['category'] + ': ' + "{:10.4f}".format(nsc) + 'ns -> ' + "{:10.4f}".format(nsi) + 'ns. '157textual_results_native += 'Native SSE is ' + format_comparison(nsi, nsc) + ' than native scalar. <br />'158159if html_result is not None:160hsc = html_result['scalar']161htmlScalarResults += [str(hsc)]162hsi = html_result['simd']163htmlSimdResults += [str(hsi)]164textual_results_html += 'JS ' + result['category'] + ': ' + "{:10.4f}".format(hsc) + 'ns -> ' + "{:10.4f}".format(hsi) + 'ns. '165textual_results_html += 'JS SSE is ' + format_comparison(hsi, hsc) + ' than JS scalar. <br />'166textual_results_html2 += 'JS ' + result['category'] + ': JS scalar is ' + format_comparison(hsc, nsc) + ' than native scalar. <br />'167textual_results_html3 += 'JS ' + result['category'] + ': JS SSE is ' + format_comparison(hsi, nsi) + ' than native SSE. <br />'168total_time_native_scalar += nsc169total_time_native_simd += nsi170total_time_html_scalar += hsc171total_time_html_simd += hsi172else:173htmlScalarResults += [str(-1)]174htmlSimdResults += [str(-1)]175176chartNumber += 1177html += '<div id="chart' + str(chartNumber) + '" style="width:100%; height:400px; margin-top: 100px;"></div>'178html += '''<script>$(function () {179$('#chart''' + str(chartNumber) + '''').highcharts({180chart: {181type: 'column'182},183title: {184text: "''' + chart_name + '''"185},186subtitle: {187text: 'Time per operation in nanoseconds'188},189xAxis: {190categories: [''' + ','.join(categories) + '''191]192},193yAxis: {194min: 0,195title: {196text: 'Time (nanoseconds)'197}198},199tooltip: {200headerFormat: '<span style="font-size:10px">{point.key}</span><table>',201pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +202'<td style="padding:0"><b>{point.y:.3f} ns</b></td></tr>',203footerFormat: '</table>',204shared: true,205useHTML: true206},207plotOptions: {208column: {209pointPadding: 0.2,210borderWidth: 0211}212},213series: [{214name: 'Native scalar',215data: [''' + ','.join(nativeScalarResults) + ''']216217}, {218name: 'Native SSE',219data: [''' + ','.join(nativeSimdResults) + ''']220221}, {222name: 'JS scalar',223data: [''' + ','.join(htmlScalarResults) + ''']224225}, {226name: 'JS SSE',227data: [''' + ','.join(htmlSimdResults) + ''']228229}]230});231});</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>'232233# Final overall score234235html += '<div id="overallscore" style="width:100%; height:400px; margin-top: 100px;"></div>'236html += '''<script>$(function () {237$('#overallscore').highcharts({238chart: {239type: 'column'240},241title: {242text: "Overall Execution Time"243},244xAxis: {245categories: ['Total time normalized to native']246},247yAxis: {248min: 0,249title: {250text: 'Relative time'251}252},253tooltip: {254headerFormat: '<span style="font-size:10px">{point.key}</span><table>',255pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +256'<td style="padding:0"><b>{point.y:.3f}x</b></td></tr>',257footerFormat: '</table>',258shared: true,259useHTML: true260},261plotOptions: {262column: {263pointPadding: 0.2,264borderWidth: 0265}266},267series: [{268name: 'Native scalar',269data: [''' + str(1.0) + ''']270271}, {272name: 'Native SSE',273data: [''' + (str(total_time_native_simd / total_time_native_scalar) if total_time_native_scalar != 0 else 'N/A') + ''']274275}, {276name: 'JS scalar',277data: [''' + (str(total_time_html_scalar / total_time_native_scalar) if total_time_native_scalar != 0 else 'N/A') + ''']278279}, {280name: 'JS SSE',281data: [''' + (str(total_time_html_simd / total_time_native_scalar) if total_time_native_scalar != 0 else 'N/A') + ''']282283}]284});285});</script>'''286287html += '</body></html>'288289open(results_file, 'w').write(html)290print('Wrote ' + str(len(html)) + ' bytes to file ' + results_file + '.')291292293if __name__ == '__main__':294suite = sys.argv[1].lower() if len(sys.argv) == 2 else None295if suite in ['sse', 'sse1']:296run_benchmark(test_file('sse/benchmark_sse1.cpp'), 'results_sse1.html', ['-msse'])297elif suite == 'sse2':298run_benchmark(test_file('sse/benchmark_sse2.cpp'), 'results_sse2.html', ['-msse2'])299elif suite == 'sse3':300run_benchmark(test_file('sse/benchmark_sse3.cpp'), 'results_sse3.html', ['-msse3'])301elif suite == 'ssse3':302run_benchmark(test_file('sse/benchmark_ssse3.cpp'), 'results_ssse3.html', ['-mssse3'])303else:304raise Exception('Usage: python test/benchmark_sse.py sse1|sse2|sse3')305306307