perftest.pl 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. # -------------------------------------------------------------------------------------------------------
  2. # Copyright (C) Microsoft. All rights reserved.
  3. # Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. # -------------------------------------------------------------------------------------------------------
  5. #
  6. # Script used for perf testing against individual benchmarks. This script supports "official" mode, which dumps an XML file
  7. # filled with all the data for analysis or exporting into Excel.
  8. #
  9. use strict;
  10. use File::Basename;
  11. use File::Spec;
  12. my $defaultIter = 35;
  13. my $iter = $defaultIter;
  14. my @testlist = ();
  15. my @testlistSwitches = ();
  16. my @variants = ("native");
  17. my %switches = ( "interpreted" => "-NoNative",
  18. "native" => "");
  19. my $other_switches = "";
  20. my $official_name;
  21. my $OFFICIAL;
  22. my $is_official = 0;
  23. my $is_baseline = 0;
  24. my $basefile = "perfbase.txt";
  25. my $testfile = "perftest.txt";
  26. my $binary = "";
  27. my $dir = "";
  28. my $skipCheckSwitch = 0; # use with non-chakra hosts
  29. my $highprecisiondate = 1;
  30. my $args;
  31. my $parse_scores = 0;
  32. my $parse_time = 1;
  33. my $parse_latency = 0;
  34. my $is_dynamicProfileRun = 1;
  35. my $profileFile="dynamicProfileInfo.dpl";
  36. my $perlScriptDir = dirname(__FILE__);
  37. my $testDescription = "";
  38. my %measured_data;
  39. my %measured;
  40. my %variances;
  41. my %baseline;
  42. my %baseline_variances;
  43. parse_args();
  44. if($dir)
  45. {
  46. $testDescription = $dir;
  47. }
  48. else
  49. {
  50. print "Specify one of the benchmark octane, sunspider, kraken or jetsream\n";
  51. print "or specify a directory of perf benchmark\n";
  52. print "and rerun this script with -baseline.\n";
  53. print "perl perftest.pl -? for more options. \n";
  54. die();
  55. }
  56. # make sure the baseline file exists
  57. if($is_baseline == 0 && !-e $basefile)
  58. {
  59. print "Baseline file $basefile not found. Rerun this script with -baseline switch.\n";
  60. print "Provide a binary path for ch.exe as well (-binary:<path>\\ch.exe).\n";
  61. die();
  62. }
  63. check_switch();
  64. $other_switches .= " -dynamicProfileCache:$profileFile" if $is_dynamicProfileRun;
  65. print "NOTE: Baseline Run\n" if $is_baseline;
  66. print "NOTE: Official Run\n" if $is_official;
  67. print "Baseline file: $basefile\n";
  68. print "Binary: $binary\n";
  69. print "Iterations: $iter\n";
  70. print "High Precision Date not used!\n" if !$highprecisiondate;
  71. print "Switches: $other_switches\n" unless ($other_switches eq "");
  72. $other_switches .= " -highprecisiondate" if $highprecisiondate;
  73. if($is_baseline)
  74. {
  75. delete_file($basefile);
  76. }
  77. else
  78. {
  79. open(my $IN, '<', $basefile) or die "Couldn't open $basefile for reading.";
  80. while(<$IN>)
  81. {
  82. if(/^([\w\-\\\.]+)\((\w+)\)\s([-+]?[0-9]*\.?[0-9]+)\s([-+]?[0-9]*\.?[0-9]+)\s([-+]?[0-9]*\.?[0-9]+)\s([-+]?[0-9]*\.?[0-9]+)$/)
  83. {
  84. $baseline{$1}{$2}{"time"}=$3;
  85. $baseline{$1}{$2}{"score"}=$5;
  86. $baseline_variances{$1}{$2}{"time"}=$4;
  87. $baseline_variances{$1}{$2}{"score"}=$6;
  88. }
  89. elsif(/^([\w\-\\\.]+)\((\w+)\)\s([-+]?[0-9]*\.?[0-9]+)\s([-+]?[0-9]*\.?[0-9]+)\s*$/)
  90. {
  91. $baseline{$1}{$2}{"time"}=$3;
  92. $baseline{$1}{$2}{"score"}=0;
  93. $baseline_variances{$1}{$2}{"time"}=$4;
  94. $baseline_variances{$1}{$2}{"score"}=0;
  95. }
  96. elsif(/^([\w\-\\\.]+)\((\w+)\)\s\s\s([-+]?[0-9]*\.?[0-9]+)\s([-+]?[0-9]*\.?[0-9]+)\s*$/)
  97. {
  98. $baseline{$1}{$2}{"time"}=0;
  99. $baseline{$1}{$2}{"score"}=$3;
  100. $baseline_variances{$1}{$2}{"time"}=0;
  101. $baseline_variances{$1}{$2}{"score"}=$4;
  102. }
  103. else
  104. {
  105. die "Couldn't match baseline file line: $_";
  106. }
  107. }
  108. close($IN);
  109. delete_file($testfile);
  110. }
  111. # run the benchmark tests
  112. print "Running $testDescription...\n";
  113. foreach my $variant(@variants)
  114. {
  115. print("\n");
  116. if(!$is_baseline)
  117. {
  118. printf("TEST - %-10s BASE TEST DIFF RATIO(%)\n", uc($variant), 0);
  119. print("---------------------------------------------------------------------------\n");
  120. }
  121. else
  122. {
  123. printf("Running %s tests...\n", uc($variant));
  124. }
  125. my %totalVariance = {"time", 0, "score", 0};
  126. my %totalBaseVariance = {"time", 0, "score", 0};
  127. my %basesum = {"time", 0, "score", 0};
  128. my %measuredsum = {"time", 0, "score", 0};
  129. foreach my $test(@testlist)
  130. {
  131. my $testLatency = $test . "Latency";
  132. if($is_baseline)
  133. {
  134. print "Running $test...\n";
  135. }
  136. delete_profile();
  137. for(my $i = 0; $i < $iter; ++$i)
  138. {
  139. # store each data point
  140. my %result = runtest($test, $variant);
  141. if ($parse_time == 1)
  142. {
  143. $measured_data{$test}{$variant}{"time"}[$i] = $result{"time"};
  144. }
  145. if ($parse_scores == 1)
  146. {
  147. $measured_data{$test}{$variant}{"score"}[$i] = $result{"score"};
  148. }
  149. if ($parse_latency == 1)
  150. {
  151. # Store Latency score as a separate test - This is used as one of the compnonents in calculating the final GM score.
  152. $measured_data{$testLatency}{$variant}{"score"}[$i] = $result{"latency"};
  153. }
  154. }
  155. if ($parse_time == 1)
  156. {
  157. # process the time result
  158. my $testName = $test;
  159. if ($parse_scores == 1)
  160. {
  161. $testName = $testName." (time)";
  162. }
  163. my %result = processResult($testName, $baseline{$test}{$variant}{"time"}, $baseline_variances{$test}{$variant}{"time"}, $measured_data{$test}{$variant}{"time"}, 0);
  164. $measured{$test}{$variant}{"time"} = $result{"measured"};
  165. $variances{$test}{$variant}{"time"} = $result{"variance"};
  166. $totalBaseVariance{"time"} += ($baseline{$test}{$variant}{"time"} * $baseline_variances{$test}{$variant}{"time"}) / 100;
  167. $basesum{"time"} += $baseline{$test}{$variant}{"time"};
  168. $totalVariance{"time"} += ($measured{$test}{$variant}{"time"} * $variances{$test}{$variant}{"time"}) / 100;
  169. $measuredsum{"time"} += $measured{$test}{$variant}{"time"};
  170. }
  171. if ($parse_scores == 1)
  172. {
  173. # process the score result
  174. my $testName = $test;
  175. if ($parse_time == 1)
  176. {
  177. $testName = $testName." (score)";
  178. }
  179. my %result = processResult($testName, $baseline{$test}{$variant}{"score"}, $baseline_variances{$test}{$variant}{"score"}, $measured_data{$test}{$variant}{"score"}, 1);
  180. $measured{$test}{$variant}{"score"} = $result{"measured"};
  181. $variances{$test}{$variant}{"score"} = $result{"variance"};
  182. }
  183. if ($parse_latency == 1)
  184. {
  185. # Check if this test has a Latency score available (Only Mandreel and Splay has latency scores as of 11/08/2013)
  186. if($measured_data{$testLatency}{$variant}{"score"}[0] != 0)
  187. {
  188. my $testName = $testLatency;
  189. my %result = processResult($testName, $baseline{$testLatency}{$variant}{"score"}, $baseline_variances{$testLatency}{$variant}{"score"}, $measured_data{$testLatency}{$variant}{"score"}, 1);
  190. $measured{$testLatency}{$variant}{"score"} = $result{"measured"};
  191. $variances{$testLatency}{$variant}{"score"} = $result{"variance"};
  192. }
  193. }
  194. }
  195. # generate the geometric means
  196. if ($parse_scores == 1)
  197. {
  198. my $measuredlog = 0;
  199. my $variancelog = 0;
  200. my $baselog = 0;
  201. my $basevariancelog = 0;
  202. foreach my $test (@testlist)
  203. {
  204. my $testLatency = $test . "Latency";
  205. if (!$is_baseline)
  206. {
  207. $baselog += log($baseline{$test}{$variant}{"score"});
  208. $basevariancelog += log(($baseline{$test}{$variant}{"score"} * $baseline_variances{$test}{$variant}{"score"}) / 100);
  209. if($parse_latency == 1)
  210. {
  211. if(exists $baseline{$testLatency})
  212. {
  213. $baselog += log($baseline{$testLatency}{$variant}{"score"});
  214. $basevariancelog += log(($baseline{$testLatency}{$variant}{"score"} * $baseline_variances{$testLatency}{$variant}{"score"}) / 100);
  215. }
  216. }
  217. }
  218. $measuredlog += log($measured{$test}{$variant}{"score"});
  219. $variancelog += log(($measured{$test}{$variant}{"score"} * $variances{$test}{$variant}{"score"}) / 100);
  220. if($parse_latency == 1)
  221. {
  222. if(exists $measured{$testLatency})
  223. {
  224. $measuredlog += log($measured{$testLatency}{$variant}{"score"});
  225. $variancelog += log(($measured{$testLatency}{$variant}{"score"} * $variances{$testLatency}{$variant}{"score"}) / 100);
  226. }
  227. }
  228. }
  229. my $count = keys(%measured);
  230. $measuredsum{"score"} = exp($measuredlog / $count);
  231. $totalVariance{"score"} = exp($variancelog / $count);
  232. $basesum{"score"} = exp($baselog / $count);
  233. $totalBaseVariance{"score"} = exp($basevariancelog / $count);
  234. }
  235. print("---------------------------------------------------------------------------\n");
  236. #print the total only if it is not a baseline run.
  237. if(!$is_baseline)
  238. {
  239. if ($parse_time == 1)
  240. {
  241. my $base_variance = ($totalBaseVariance{"time"} / $basesum{"time"}) * 100;
  242. my $test_variance = ($totalVariance{"time"} / $measuredsum{"time"}) * 100;
  243. my $diff = $measuredsum{"time"} - $basesum{"time"};
  244. my $ratio = ($measuredsum{"time"} / $basesum{"time"} - 1) * 100.0;
  245. my $investigate = "";
  246. if($test_variance < abs($ratio) && $base_variance < abs($ratio))
  247. {
  248. if($ratio > 4 )
  249. {
  250. $investigate = "<-CHECK";
  251. }
  252. if($ratio < -4)
  253. {
  254. $investigate = "<-IMPROVED";
  255. }
  256. }
  257. printf("%-24.24s %6.1f +-%2.1f%%\t%6.1f +-%2.1f%%\t%6.1f\t%5.1f%% %s\n", "TOTAL TIME", $basesum{"time"}, $base_variance, $measuredsum{"time"}, $test_variance, $diff, $ratio, $investigate);
  258. }
  259. if ($parse_scores == 1)
  260. {
  261. my $base_variance = ($totalBaseVariance{"score"} / $basesum{"score"}) * 100;
  262. my $test_variance = ($totalVariance{"score"} / $measuredsum{"score"}) * 100;
  263. my $diff = $measuredsum{"score"} - $basesum{"score"};
  264. my $ratio = ($measuredsum{"score"} / $basesum{"score"} - 1) * 100.0;
  265. my $investigate = "";
  266. if($test_variance < abs($ratio) && $base_variance < abs($ratio))
  267. {
  268. if($ratio > 4 )
  269. {
  270. $investigate = "<-IMPROVED";
  271. }
  272. if($ratio < -4)
  273. {
  274. $investigate = "<-CHECK";
  275. }
  276. }
  277. printf("%-24.24s %6.1f +-%2.1f%%\t%6.1f +-%2.1f%%\t%6.1f\t%5.1f%% %s\n", "MEAN SCORE", $basesum{"score"}, $base_variance, $measuredsum{"score"}, $test_variance, $diff, $ratio, $investigate);
  278. }
  279. print("\n");
  280. }
  281. }
  282. # handle the official run
  283. if($is_official)
  284. {
  285. official_header();
  286. # record each test
  287. foreach my $test(@testlist)
  288. {
  289. official_start_test($test);
  290. foreach my $variant(@variants)
  291. {
  292. official_start_variant($variant);
  293. for(my $i = 0; $i < $iter; ++$i)
  294. {
  295. official_record($measured_data{$test}{$variant}{"time"}[$i]);
  296. }
  297. official_end_variant($variant);
  298. }
  299. official_end_test($test);
  300. }
  301. # record the total
  302. official_start_test("TOTAL");
  303. foreach my $variant(@variants)
  304. {
  305. official_start_variant($variant);
  306. for(my $i = 0; $i < $iter; ++$i)
  307. {
  308. my $sum = 0;
  309. # for each iteration, sum across all tests
  310. foreach my $test(@testlist)
  311. {
  312. $sum += $measured_data{$test}{$variant}{"time"}[$i];
  313. }
  314. official_record($sum);
  315. }
  316. official_end_variant($variant);
  317. }
  318. official_end_test("TOTAL");
  319. official_footer();
  320. exit(0);
  321. }
  322. # output to the baseline file or test result file and exit
  323. saveResult($is_baseline ? $basefile : $testfile);
  324. sub saveResult()
  325. {
  326. my $result_file = shift;
  327. open(my $OUT, '>', $result_file) or die "Couldn't open $result_file for writing.";
  328. foreach my $test(@testlist)
  329. {
  330. foreach my $variant(@variants)
  331. {
  332. print $OUT "$test($variant) $measured{$test}{$variant}{'time'} $variances{$test}{$variant}{'time'} $measured{$test}{$variant}{'score'} $variances{$test}{$variant}{'score'}\n";
  333. my $testLatency = $test . "Latency";
  334. if(exists $measured{$testLatency})
  335. {
  336. #Note: There are extra spaces in this output - which is deliberately added to match the regex (to read from the baseline file)
  337. print $OUT "$testLatency($variant) $measured{$testLatency}{$variant}{'score'} $variances{$testLatency}{$variant}{'score'}\n";
  338. }
  339. }
  340. }
  341. close($OUT);
  342. exit(0);
  343. }
  344. sub processResult()
  345. {
  346. my $test = shift;
  347. my $baseline = shift;
  348. my $baseline_variance = shift;
  349. my $data = shift;
  350. my $bigger_is_better = shift;
  351. my $value = 0;
  352. my $variance = 0;
  353. my %result = {"measured", 0, "variance", 0};
  354. # sort the timings
  355. if ($bigger_is_better == 1)
  356. {
  357. @{$data} = sort {$b <=> $a} @{$data};
  358. }
  359. else
  360. {
  361. @{$data} = sort {$a <=> $b} @{$data};
  362. }
  363. # discard the minimum/maximum 10%
  364. my $count = @{$data};
  365. if($count >= 10)
  366. {
  367. $count = int($count * 9 / 10);
  368. }
  369. for(my $i = 0; $i < $count; ++$i)
  370. {
  371. $value += @{$data}[$i];
  372. }
  373. my $value = $value / $count;
  374. if ($value > 0)
  375. {
  376. for(my $i = 0; $i < $count; ++$i)
  377. {
  378. $variance += (@{$data}[$i] - $value) * (@{$data}[$i] - $value);
  379. }
  380. $variance = (sqrt($variance / $count) / $value) * 100;
  381. if ($variance == 0)
  382. {
  383. $variance = 0.0001; # to avoid divide by zero and ln(0) errors
  384. }
  385. }
  386. else
  387. {
  388. $variance = 0.0001; # to avoid divide by zero and ln(0) errors
  389. }
  390. #print the results only if it is not a baseline run.
  391. if(!$is_baseline)
  392. {
  393. my $diff = $value - $baseline;
  394. my $ratio = 0;
  395. if ($baseline > 0)
  396. {
  397. $ratio = ($diff / $baseline) * 100.0;
  398. }
  399. else
  400. {
  401. # prevent divide by zero. the lack of precision is acceptable if the tests are taking <1ms
  402. $ratio = ($diff / 1) * 100.0;
  403. }
  404. my $investigate = "";
  405. if($variance < abs($ratio) && $baseline_variance < abs($ratio))
  406. {
  407. if($ratio > 4 )
  408. {
  409. if ($bigger_is_better == 1)
  410. {
  411. $investigate = "<-IMPROVED";
  412. }
  413. else
  414. {
  415. $investigate = "<-CHECK";
  416. }
  417. }
  418. if($ratio < -4)
  419. {
  420. if ($bigger_is_better == 1)
  421. {
  422. $investigate = "<-CHECK";
  423. }
  424. else
  425. {
  426. $investigate = "<-IMPROVED";
  427. }
  428. }
  429. }
  430. printf ("%-24.24s %6.1f +-%2.1f%%\t%6.1f +-%2.1f%%\t%6.1f\t%5.1f%% %s\n", $test, $baseline, $baseline_variance, $value, $variance, $diff, $ratio, $investigate);
  431. }
  432. $result{"measured"} = $value;
  433. $result{"variance"} = $variance;
  434. return %result;
  435. }
  436. sub runtest
  437. {
  438. my $testcasename = shift;
  439. my $variant = shift;
  440. my %results = ("time", -1, "score", -1);
  441. #TODO investigate what was meant to go here, other than adding whitespace on the end
  442. #This is a hash slice syntax on an array which is empty, so makes no sense at all
  443. #$other_switches .= " " . @testlistSwitches{$testcasename};
  444. if(!$dir)
  445. {
  446. system("$binary $switches{$variant} $other_switches $testcasename.js > _time.txt");
  447. }
  448. else
  449. {
  450. my $testpath = File::Spec->catfile($dir, $testcasename);
  451. system("$binary $switches{$variant} $other_switches $testpath.js > _time.txt");
  452. }
  453. open(my $IN, '<', "_time.txt") or die;
  454. my $i = 0;
  455. while(<$IN>)
  456. {
  457. if(/###\sTIME:\s(\d+(\.\d+)*)\sms/)
  458. {
  459. $results{"time"} = $1;
  460. }
  461. if(/###\sSCORE:\s(\d+)/)
  462. {
  463. $results{"score"} = $1;
  464. }
  465. if(/###\sLATENCY:\s(\d+)/)
  466. {
  467. $results{"latency"} = $1;
  468. }
  469. }
  470. close $IN;
  471. if ($testDescription == "custom")
  472. {
  473. if ($results{"time"} != -1 || $results{"score"} != -1)
  474. {
  475. return %results;
  476. }
  477. }
  478. if(($parse_time == 1 && $results{"time"} == -1) || ($parse_scores == 1 && $results{"score"} == -1))
  479. {
  480. print "ERROR: test produced invalid output while running $testcasename.js\n";
  481. exit(1);
  482. }
  483. return %results;
  484. }
  485. sub badswitch
  486. {
  487. die "invalid switch combination";
  488. }
  489. sub usage
  490. {
  491. print "Usage: perftest.pl [options]\n";
  492. print "Options:\n";
  493. print " -baseline Generates a baseline, updating your local baseline file. \n";
  494. print " NOTE: use only with base binary with clean clone from the Chakracore repo\n";
  495. print " -basefile:<file> Uses <file> as your perf baseline (default: perfbase.txt)\n";
  496. print " -testfile:<file> Uses <file> to save your perf test result (default: perftest.txt)\n";
  497. print " -dir:<dirpath> Uses the test files in the <dirpath>.\n";
  498. print " -binary:<filepath> Uses <filepath> to run the JS files.\n";
  499. print " -skipCheckSwitch Skip checking binary command line switches (use with non-chakra hosts)";
  500. print " -iterations:<iter> Number of iterations to run tests (default: 11)\n";
  501. print " -official:<name> Generates an official report into results-<name>.xml\n";
  502. print " -native Only run -native variation (default)\n";
  503. print " -interpreted Only run -interpreted variation\n";
  504. print " -nativeAndinterpreted Run -interpreted along with -native variation\n";
  505. print " -nodynamicProfile Run without dynamic profile info\n";
  506. print " -dynamicProfile Force Run with dynamic profile info\n";
  507. print " -sunspider Run the sunspider 1.0.2 benchmark\n";
  508. print " -kraken Run the kraken benchmark\n";
  509. print " -octane Run the Octane 2.0 benchmark\n";
  510. print " -jetstream Run the JetStream benchmark (only non octane and sunspider tests)\n";
  511. print " -file:<file> Run the specified js file\n";
  512. print " -args:<other args> Other arguments to ch.exe\n";
  513. print " -score Test output scores\n";
  514. }
  515. sub parse_args
  516. {
  517. my $forceDynamicProfileOn;
  518. my $forceDynamicProfileOff;
  519. if(@ARGV == 1 && $ARGV[0] =~ /[-\/]\?/)
  520. {
  521. usage();
  522. exit(0);
  523. }
  524. for(my $i = 0; $i < @ARGV; ++$i)
  525. {
  526. if($ARGV[$i] =~ /[-\/]baseline/)
  527. {
  528. $is_baseline = 1;
  529. badswitch() if $is_official;
  530. }
  531. elsif($ARGV[$i] =~ /[-\/]basefile:(.*)$/)
  532. {
  533. $basefile = $1;
  534. badswitch() if $is_official;
  535. }
  536. elsif($ARGV[$i] =~ /[-\/]testfile:(.*)$/)
  537. {
  538. $testfile = $1;
  539. badswitch() if $is_official;
  540. }
  541. elsif($ARGV[$i] =~ /[-\/]binary:(.*)$/)
  542. {
  543. $binary = $1;
  544. }
  545. elsif($ARGV[$i] =~ /[-\/]skipCheckSwitch/)
  546. {
  547. $skipCheckSwitch = 1;
  548. }
  549. elsif($ARGV[$i] =~ /[-\/]dir:(.*)$/)
  550. {
  551. if($1)
  552. {
  553. $dir = $1;
  554. print "dir = $1\n";
  555. }
  556. else
  557. {
  558. $dir= ".";
  559. print "dir = $1\n";
  560. }
  561. #opens the directory and read the files in it
  562. opendir(dirHandle,$dir) || die("Cannot open directory");
  563. @testlist = grep (/.js/, readdir(dirHandle));
  564. closedir(dirHandle);
  565. for (@testlist)
  566. {
  567. s/(.*).js/$1/;
  568. }
  569. $is_dynamicProfileRun = 0;
  570. }
  571. elsif($ARGV[$i] =~ /[-\/]iterations:(\d+)$/)
  572. {
  573. $iter = $1;
  574. }
  575. elsif($ARGV[$i] =~ /[-\/]official:(.*)$/)
  576. {
  577. $is_official = 1;
  578. $official_name = $1;
  579. open($OFFICIAL, '>', "results-$official_name.xml") or die "Cannot open official results XML file for writing";
  580. badswitch() if $is_baseline;
  581. }
  582. elsif($ARGV[$i] =~ /[-\/]native/)
  583. {
  584. @variants = ("native");
  585. }
  586. elsif($ARGV[$i] =~ /[-\/]interpreted/)
  587. {
  588. @variants = ("interpreted");
  589. }
  590. elsif($ARGV[$i] =~ /[-\/]nativeAndInterpreted/)
  591. {
  592. @variants = ("native", "interpreted");
  593. }
  594. elsif($ARGV[$i] =~ /[-\/]octane/)
  595. {
  596. if($iter == $defaultIter)
  597. {
  598. $iter = 10;
  599. }
  600. @testlist = ("box2d", "code-load", "crypto", "deltablue", "earley-boyer", "gbemu", "mandreel", "navier-stokes", "pdfjs", "raytrace", "regexp", "richards", "splay", "typescript", "zlib");
  601. $testDescription = "octane 2.0 benchmark";
  602. $parse_time = 0;
  603. $parse_scores = 1;
  604. $parse_latency = 1;
  605. $dir = "Octane";
  606. $basefile = "perfbase$dir.txt";
  607. $testfile = "perftest$dir.txt";
  608. $is_dynamicProfileRun = 0; # Currently octane dyna-pogo info is not avialable in the browser - remove this when it is.
  609. }
  610. elsif($ARGV[$i] =~ /[-\/]jetstream/)
  611. {
  612. if($iter == $defaultIter)
  613. {
  614. $iter = 5;
  615. }
  616. @testlist = ("bigfib.cpp", "container.cpp", "dry.c", "float-mm.c", "gcc-loops.cpp", "hash-map", "n-body.c", "quicksort.c", "towers.c", "cdjs");
  617. $testDescription = "JetStream benchmark";
  618. $parse_time = 0;
  619. $parse_scores = 1;
  620. $parse_latency = 0;
  621. $dir = "jetstream";
  622. $basefile = "perfbase$dir.txt";
  623. $testfile = "perftest$dir.txt";
  624. $is_dynamicProfileRun = 0; # Currently dyna-pogo info is not avialable in the browser - remove this when it is.
  625. }
  626. elsif($ARGV[$i] =~ /[-\/]kraken/i)
  627. {
  628. if($iter == $defaultIter)
  629. {
  630. $iter = 10;
  631. }
  632. @testlist = ("ai-astar", "audio-beat-detection", "audio-dft", "audio-fft", "audio-oscillator", "imaging-darkroom",
  633. "imaging-desaturate", "imaging-gaussian-blur", "json-parse-financial", "json-stringify-tinderbox",
  634. "stanford-crypto-aes", "stanford-crypto-ccm", "stanford-crypto-pbkdf2", "stanford-crypto-sha256-iterative");
  635. $testDescription = "kraken benchmark";
  636. $dir = "Kraken";
  637. $basefile = "perfbase$dir.txt";
  638. $testfile = "perftest$dir.txt";
  639. $highprecisiondate = 0;
  640. }
  641. elsif($ARGV[$i] =~ /[-\/]sunspider/i)
  642. {
  643. @testlist = ("3d-cube", "3d-morph", "3d-raytrace", "access-binary-trees", "access-fannkuch",
  644. "access-nbody", "access-nsieve", "bitops-3bit-bits-in-byte", "bitops-bits-in-byte",
  645. "bitops-bitwise-and", "bitops-nsieve-bits", "controlflow-recursive", "crypto-aes", "crypto-md5",
  646. "crypto-sha1", "date-format-tofte", "date-format-xparb", "math-cordic", "math-partial-sums",
  647. "math-spectral-norm", "regexp-dna", "string-base64", "string-fasta", "string-tagcloud",
  648. "string-unpack-code", "string-validate-input");
  649. $dir = "SunSpider";
  650. $basefile = "perfbase$dir.txt";
  651. $testfile = "perftest$dir.txt";
  652. $is_dynamicProfileRun = 1;
  653. }
  654. elsif($ARGV[$i] =~ /[-\/]file:(.*).js$/i)
  655. {
  656. # only supports octane, add additional support here for jetstream
  657. my %scoreTests = ( "box2d" => 1, "code-load" => 1, "crypto" => 1, "deltablue" => 1,
  658. "earley-boyer" => 1, "gbemu" => 1, "mandreel" => 1, "navier-stokes" => 1,
  659. "pdfjs" => 1, "raytrace" => 1, "regexp" => 1, "richards" => 1, "splay" => 1,
  660. "zlib" => 1, "typescript" => 1);
  661. @testlist = ($1);
  662. my $test = lc $1;
  663. if (exists $scoreTests{$test}) {
  664. $parse_scores = 1;
  665. $parse_time = 0;
  666. $is_dynamicProfileRun = 0; # Currently octane dyna-pogo info is not avialable in the browser - remove this when it is.
  667. if($iter == $defaultIter)
  668. {
  669. $iter = 10;
  670. }
  671. }
  672. $testDescription = "custom";
  673. }
  674. elsif($ARGV[$i] =~ /[-\/]score/i)
  675. {
  676. $parse_scores = 1;
  677. $parse_time = 0;
  678. }
  679. elsif($ARGV[$i] =~ /[-\/]Off:(.*)$/i)
  680. {
  681. $other_switches .= " -Off:" . $1;
  682. }
  683. elsif($ARGV[$i] =~ /[-\/]On:(.*)$/i)
  684. {
  685. $other_switches .= " -On:" . $1;
  686. }
  687. elsif($ARGV[$i] =~ /[-\/]args:(.*)$/i)
  688. {
  689. $other_switches .= " " . $1;
  690. }
  691. elsif($ARGV[$i] =~ /[-\/]noDynamicProfile/i)
  692. {
  693. $forceDynamicProfileOff = 1;
  694. }
  695. elsif($ARGV[$i] =~ /[-\/]dynamicProfile/i)
  696. {
  697. $forceDynamicProfileOn = 1;
  698. }
  699. else
  700. {
  701. print "ERROR: Invalid argument $ARGV[$i] to script\n";
  702. die;
  703. }
  704. }
  705. if($forceDynamicProfileOff)
  706. {
  707. $is_dynamicProfileRun = 0;
  708. }
  709. if($forceDynamicProfileOn)
  710. {
  711. $is_dynamicProfileRun = 1;
  712. }
  713. if ($binary eq "")
  714. {
  715. print "ERROR: Provide a binary path for ch.exe (-binary:<path>\\ch.exe).\n";
  716. die;
  717. }
  718. }
  719. sub official_footer
  720. {
  721. print $OFFICIAL "</data>\n";
  722. close($OFFICIAL);
  723. }
  724. sub official_header
  725. {
  726. print $OFFICIAL "<data name=\"ChakraCore Perf Tests\">\n";
  727. }
  728. sub official_start_variant
  729. {
  730. my $variant = shift;
  731. print $OFFICIAL "\t<variant name=\"$variant\">\n";
  732. }
  733. sub official_end_variant
  734. {
  735. print $OFFICIAL "\t</variant>\n";
  736. }
  737. sub official_start_test
  738. {
  739. my $testname = shift;
  740. print $OFFICIAL "<test name=\"$testname\">\n";
  741. }
  742. sub official_record
  743. {
  744. my $time = shift;
  745. print $OFFICIAL "\t\t<iteration time_ms=\"$time\"/>\n";
  746. }
  747. sub official_end_test
  748. {
  749. print $OFFICIAL "</test>\n";
  750. }
  751. sub check_switch
  752. {
  753. # Use -skipCheckSwitch to avoid checking command line switches with
  754. # non-chakra hosts (Following "... -?" may enter host command loop.)
  755. if ($skipCheckSwitch)
  756. {
  757. return;
  758. }
  759. system("$binary -? > _time.txt");
  760. open(my $IN, '<', "_time.txt") or die;
  761. my $dynamicProfileSupported = 0;
  762. my $highprecisiondateSupported = 0;
  763. while(<$IN>)
  764. {
  765. if(/\sHighPrecisionDate/)
  766. {
  767. $highprecisiondateSupported = 1;
  768. }
  769. if(/\sDynamicProfileCache/)
  770. {
  771. $dynamicProfileSupported = 1;
  772. }
  773. }
  774. close($IN);
  775. if($is_dynamicProfileRun && !$dynamicProfileSupported)
  776. {
  777. print "Warning: Persistent Dynamic profile is not supported! \n";
  778. $is_dynamicProfileRun = 0;
  779. }
  780. if(!$highprecisiondateSupported)
  781. {
  782. $highprecisiondate = 0;
  783. }
  784. }
  785. sub delete_profile
  786. {
  787. if($is_dynamicProfileRun)
  788. {
  789. delete_file($profileFile);
  790. }
  791. }
  792. sub delete_file()
  793. {
  794. my $f = shift;
  795. if(-e $f)
  796. {
  797. unlink($f);
  798. if(-e $f)
  799. {
  800. print "File could not be deleted: $f\n";
  801. die();
  802. }
  803. }
  804. }