Skip to content
This repository has been archived by the owner on Jan 13, 2022. It is now read-only.

Commit

Permalink
Added setup script, php fpm support, modified batch run to be able to…
Browse files Browse the repository at this point in the history
… configure databases, fixed tc-print, and perf.
  • Loading branch information
mofarrell committed Mar 10, 2017
1 parent c7de4aa commit 1b3fa02
Show file tree
Hide file tree
Showing 12 changed files with 364 additions and 159 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ vendor/
core
core.*
composer.phar
perf.data
processed-perf.data
53 changes: 49 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ As a regular user:

composer.phar install # see https://getcomposer.org/download/
hhvm perf.php --wordpress --php5=/path/to/bin/php-cgi # also works with php7
hhvm perf.php --wordpress --php=/path/to/bin/php-fpm # also works with php7
hhvm perf.php --wordpress --hhvm=/path/to/hhvm

Running with --hhvm gives some additional server-side statistics. It is usual
for HHVM to report more requests than siege - some frameworks do call-back
requests to the current webserver.

:heavy_exclamation_mark: If you run with a debug build you may hit timeouts and
other issues.

Batch Usage
===========

Expand All @@ -45,18 +49,24 @@ See batch-run.json.example to get an idea of how to create batch-run.json.
Requirements
============

On Ubuntu you can run scripts/setup.sh. This should provision your machine with
everything you need to begin running the benchmarks.

This installs:

- composer
- nginx
- siege 2.x
- siege (versions 2.x, or 3.1.x or 4.0.3)
- unzip
- A mysql server on 127.0.0.1:3306
- hhvm

I've been using the current versions available from yum on Centos 6.3. HHVM is
required as this is written in Hack.

Siege 3.x is not supported; as of writing, all 3.x releases have bugs that make
it unable to correctly make the benchmark requests.
Siege 3.0.x is not supported; as of writing, all 3.0.x releases have bugs that make
it unable to correctly make the benchmark requests. 4.0.0, 4.0.1, 4.0.2 all
automatically request resources on pages, and should not be used for benchmarking.

The Targets
===========
Expand Down Expand Up @@ -188,14 +198,49 @@ loaded to provide a slightly more rounded workload.
Profiling
=========

Perf
----
perf.php can keep the suite running indefinitely:

hhvm perf.php --i-am-not-benchmarking --no-time-limit --wordpress --hhvm=$HHVM_BIN

You can then attach 'perf' or another profiler to the running HHVM or php-cgi process, once the 'benchmarking'
phase has started.

Direct support (especially for XHProf) is planned, but not yet implemented.
There is also a script to run perf for you at the apropriate moment:

hhvm perf.php --i-am-not-benchmarking --wordpress --hhvm=$HHVM_BIN --exec-after-warmup="./scripts/perf.sh -e cycles"

This will record 25 seconds of samples. To see where most time is spent you can
dive into the data using perf, or use the perf rollup script as follows:

sudo perf script -F comm,ip,sym | hhvm -vEval.EnableHipHopSyntax=true <HHVM SRC>/hphp/tools/perf-rollup.php

In order to have all the symbols from the the translation cache you
may need to change the owner of /tmp/hhvm-<PID>.map to root.


TC-print
--------
TC-print will use data from perf to determine the hotest functions and
translations. Run the benchmark as follows:

hhvm perf.php --i-am-not-benchmarking --wordpress --hhvm=$HHVM_BIN --exec-after-warmup="./scripts/perf.sh -e cycles" --tcprint

In order to have all the symbols from the the translation cache you
may need to change the owner of /tmp/hhvm-<PID>.map to root.

We process the perf data before passing it along to tc-print
sudo perf script -f -F hw:comm,event,ip,sym | <HHVM SRC>/hphp/tools/perf-script-raw.py > processed-perf.data

tc-print is only built if the appropriate disassembly tools are available. On
x86 this is LibXed. Consider building hhvm using:

cmake . -DLibXed_INCLUDE_DIR=<path to xed include> -DLibXed_LIBRARY=<path to libxed.a>

Use tc-print with the generated perf.data:
<HHVM SRC>hphp/tools/tc-print/tc-print -c /tmp/<TMP DIR FOR BENCHMARK RUN>/conf.hdf -p processed-perf.data


Contributing
============
Expand Down
14 changes: 10 additions & 4 deletions base/DatabaseInstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,16 @@ public function installDatabase(): bool {
}

private function getRootConnection(): resource {
print "MySQL admin user (default is 'root'): ";
$this->username = trim(fgets(STDIN)) ?: 'root';
fprintf(STDERR, '%s', 'MySQL admin password: ');
$this->password = trim(fgets(STDIN));
if ($this->options->dbUsername !== null
&& $this->options->dbPassword !== null) {
$this->username = $this->options->dbUsername;
$this->password = $this->options->dbPassword;
} else {
print "MySQL admin user (default is 'root'): ";
$this->username = trim(fgets(STDIN)) ?: 'root';
fprintf(STDERR, '%s', 'MySQL admin password: ');
$this->password = trim(fgets(STDIN));
}
$conn = mysql_connect('127.0.0.1', $this->username, $this->password);
if ($conn === false) {
throw new Exception('Failed to connect: '.mysql_error());
Expand Down
49 changes: 13 additions & 36 deletions base/HHVMDaemon.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ protected function getArguments(): Vector<string> {
'-v',
'Eval.Jit=1',
'-d',
'hhvm.log.file='.$this->options->tempDir.'/hhvm_error.log',
'-d',
'pid='.escapeshellarg($this->getPidFilePath()),
'-c',
OSS_PERFORMANCE_ROOT.'/conf/php.ini',
Expand Down Expand Up @@ -123,8 +125,6 @@ protected function getArguments(): Vector<string> {
$args->add('Server.SourceRoot='.$sourceRoot);
}
if ($this->options->tcprint !== null) {
$args->add('-v');
$args->add('Eval.JitTransCounters=true');
$args->add('-v');
$args->add('Eval.DumpTC=true');
}
Expand Down Expand Up @@ -273,46 +273,23 @@ public function stop(): void {

public function writeStats(): void {
$tcprint = $this->options->tcprint;
if ($tcprint) {
$conf = $this->options->tempDir.'/conf.hdf';
$args = Vector {};
$hdf = false;
foreach ($this->getArguments() as $arg) {
if ($hdf)
$args->add($arg);
$hdf = $arg === '-v';
}
$confData = implode("\n", $args);

file_put_contents($conf, $confData);
$args = Vector {$tcprint, '-c', $conf};
$conf = $this->options->tempDir.'/conf.hdf';
$args = Vector {};
$hdf = false;
foreach ($this->getArguments() as $arg) {
if ($hdf)
$args->add($arg);
$hdf = $arg === '-v';
}
$confData = implode("\n", $args);

file_put_contents($conf, $confData);
if ($tcprint) {
$result = $this->adminRequest('/vm-dump-tc');
invariant(
$result === 'Done' && file_exists('/tmp/tc_dump_a'),
'Failed to dump TC',
);

if ($this->options->tcAlltrans) {
$alltrans = Utils::RunCommand($args);
file_put_contents('tc-all', $alltrans);
}

if ($this->options->tcToptrans) {
$new_args = new Vector($args);
$new_args->add('-t');
$new_args->add('100');
$toptrans = Utils::RunCommand($new_args);
file_put_contents('tc-top-trans', $toptrans);
}

if ($this->options->tcTopfuncs) {
$new_args = new Vector($args);
$new_args->add('-T');
$new_args->add('100');
$topfuncs = Utils::RunCommand($new_args);
file_put_contents('tc-top-funcs', $topfuncs);
}
}

if ($this->options->pcredump) {
Expand Down
105 changes: 76 additions & 29 deletions base/PHP5Daemon.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,51 @@ public function __construct(private PerfOptions $options) {
$this->target = $options->getTarget();
parent::__construct((string) $options->php5);

$output = [];
$check_command = implode(
' ',
(Vector {
$options->php5,
'-q',
'-c',
OSS_PERFORMANCE_ROOT.'/conf',
__DIR__.'/php-src_config_check.php',
})->map($x ==> escapeshellarg($x)),
);
if ($options->fpm) {
$output = [];
$check_command = implode(
' ',
(Vector {
$options->php5,
'-i',
'-c',
OSS_PERFORMANCE_ROOT.'/conf',
})->map($x ==> escapeshellarg($x)),
);

// Basic check for opcode caching.
if ($options->traceSubProcess) {
fprintf(STDERR, "%s\n", $check_command);
}
exec($check_command, $output);
$check = array_search('Opcode Caching => Up and Running', $output, true);
invariant($check, 'Got invalid output from php-fpm -i');
} else {
$output = [];
$check_command = implode(
' ',
(Vector {
$options->php5,
'-q',
'-c',
OSS_PERFORMANCE_ROOT.'/conf',
__dir__.'/php-src_config_check.php',
})->map($x ==> escapeshellarg($x)),
);

if ($options->traceSubProcess) {
fprintf(STDERR, "%s\n", $check_command);
if ($options->traceSubProcess) {
fprintf(STDERR, "%s\n", $check_command);
}
exec($check_command, $output);
$checks = json_decode(implode("\n", $output), /* as array = */ true);
invariant($checks, 'Got invalid output from php-src_config_check.php');
BuildChecker::Check(
$options,
(string) $options->php5,
$checks,
Set {'PHP_VERSION', 'PHP_VERSION_ID'},
);
}
exec($check_command, $output);
$checks = json_decode(implode("\n", $output), /* as array = */ true);
invariant($checks, 'Got invalid output from php-src_config_check.php');
BuildChecker::Check(
$options,
(string) $options->php5,
$checks,
Set {'PHP_VERSION', 'PHP_VERSION_ID'},
);
}

public function start(): void {
Expand All @@ -51,12 +72,37 @@ public function start(): void {
}

protected function getArguments(): Vector<string> {
$args = Vector {
'-b',
'127.0.0.1:'.PerfSettings::BackendPort(),
'-c',
OSS_PERFORMANCE_ROOT.'/conf/',
};
if ($this->options->fpm) {
echo 'Creating PHP FPM config';
$path = $this->options->tempDir.'/php-fpm.conf';
$config = file_get_contents(OSS_PERFORMANCE_ROOT.'/conf/php-fpm.conf.in');
$config = str_replace(
"__FASTCGI_PORT__",
PerfSettings::BackendPort(),
$config
);
$config = str_replace(
"__TMP_DIR__",
$this->options->tempDir,
$config
);
file_put_contents($path, $config);

$args = Vector {
'-F',
'--fpm-config',
$path,
'-c',
OSS_PERFORMANCE_ROOT.'/conf/',
};
} else {
$args = Vector {
'-b',
'127.0.0.1:'.PerfSettings::BackendPort(),
'-c',
OSS_PERFORMANCE_ROOT.'/conf/',
};
}

if (count($this->options->phpExtraArguments) > 0) {
$args->addAll($this->options->phpExtraArguments);
Expand Down Expand Up @@ -102,7 +148,8 @@ private function isPHPCGIProcess(int $pid): bool {
if (!file_exists($exe)) {
return false;
}
return (bool) preg_match('/php.*-cgi/', readlink($exe));
return (bool) preg_match('/php.*-cgi/', readlink($exe)) ||
(bool) preg_match('/php.*-fpm/', readlink($exe));
}

protected function getEnvironmentVariables(): Map<string, string> {
Expand Down
Loading

0 comments on commit 1b3fa02

Please sign in to comment.