Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3453112

Browse files
committed
measure startup, each bench run and shutdown separately
1 parent 76b989c commit 3453112

File tree

2 files changed

+70
-32
lines changed

2 files changed

+70
-32
lines changed

‎benchmark/benchmark.php

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ function runSymfonyDemo(bool $jit): array {
6363
cloneRepo($dir, 'https://github.com/php/benchmarking-symfony-demo-2.2.3.git');
6464
runPhpCommand([$dir . '/bin/console', 'cache:clear']);
6565
runPhpCommand([$dir . '/bin/console', 'cache:warmup']);
66-
return runValgrindPhpCgiCommand('symfony-demo', [$dir . '/public/index.php'], cwd: $dir, jit: $jit, warmup: 50, repeat: 50);
66+
67+
return runValgrindPhpCgiCommand('symfony-demo', [$dir . '/public/index.php'], cwd: $dir, jit: $jit, repeat: 100);
6768
}
6869

6970
function runWordpress(bool $jit): array {
@@ -86,7 +87,8 @@ function runWordpress(bool $jit): array {
8687

8788
// Warmup
8889
runPhpCommand([$dir . '/index.php'], $dir);
89-
return runValgrindPhpCgiCommand('wordpress', [$dir . '/index.php'], cwd: $dir, jit: $jit, warmup: 50, repeat: 50);
90+
91+
return runValgrindPhpCgiCommand('wordpress', [$dir . '/index.php'], cwd: $dir, jit: $jit, repeat: 100);
9092
}
9193

9294
function runPhpCommand(array $args, ?string $cwd = null): ProcessResult {
@@ -98,45 +100,86 @@ function runValgrindPhpCgiCommand(
98100
array $args,
99101
?string $cwd = null,
100102
bool $jit = false,
101-
int $warmup = 0,
102103
int $repeat = 1,
103104
): array {
104105
global $phpCgi;
105106

106-
$profileOut = __DIR__ . "/profiles/callgrind.out.$name";
107+
$profileOut = __DIR__ . "/profiles/callgrind.$name";
107108
if ($jit) {
108-
$profileOut .= '.jit';
109+
$profileOut .= '-jit';
109110
}
110111

111112
$process = runCommand([
112113
'valgrind',
113114
'--tool=callgrind',
114115
'--dump-instr=yes',
116+
'--collect-jumps=yes',
115117
"--callgrind-out-file=$profileOut",
118+
'--verbose',
116119
'--',
117120
$phpCgi,
118-
'-T' . ($warmup ? $warmup . ',' : '') . $repeat,
121+
'-T' . $repeat,
119122
'-d max_execution_time=0',
120123
'-d opcache.enable=1',
121124
'-d opcache.jit=' . ($jit ? 'tracing' : 'disable'),
122125
'-d opcache.jit_buffer_size=128M',
123126
'-d opcache.validate_timestamps=0',
124127
...$args,
125128
]);
126-
$valgrindMetrics = extractMetricsFromValgrindOutput($process->stderr);
127-
$instructions = $valgrindMetrics['Ir'];
128-
if ($repeat > 1) {
129-
$instructions = gmp_strval(gmp_div_q($instructions, $repeat));
129+
130+
// collect metrics for startup, each benchmark run and shutdown
131+
$metricsArr = [];
132+
foreach (['startup' => 1, ...range(2, $repeat + 1), 'shutdown' => ''] as $k => $kCallgrindOut) {
133+
$profileOutSpecific = $profileOut . '.' . $k;
134+
rename($profileOut . ($kCallgrindOut === '' ? '' : '.' . $kCallgrindOut), $profileOutSpecific);
135+
136+
$metricsArr[$k] = extractMetricsFromCallgrindFile($profileOutSpecific);
137+
}
138+
139+
// print all collected metrics
140+
print_r($metricsArr);
141+
142+
// find the fastest benchmark run
143+
$bestRunIndex = 0;
144+
foreach (range(0, $repeat - 1) as $k) {
145+
if ($metricsArr[$k]['Ir'] < $metricsArr[$bestRunIndex]['Ir']) {
146+
$bestRunIndex = $k;
147+
}
130148
}
131-
return ['instructions' => $instructions];
149+
150+
// remove non-fastest profiles from artifacts
151+
foreach (range(0, $repeat - 1) as $k) {
152+
$profileOutSpecific = $profileOut . '.' . $k;
153+
154+
if ($k !== $bestRunIndex) {
155+
unlink($profileOutSpecific);
156+
}
157+
}
158+
159+
// annotate profiles for artifacts
160+
foreach (['startup', $bestRunIndex, 'shutdown'] as $k) {
161+
$profileOutSpecific = $profileOut . '.' . $k;
162+
163+
runCommand([
164+
'callgrind_annotate',
165+
'--threshold=100',
166+
'--auto=yes',
167+
'--show-percs=no',
168+
$profileOutSpecific,
169+
new UnescapedArg('>'),
170+
"$profileOutSpecific.txt",
171+
]);
172+
}
173+
174+
return ['instructions' => $metricsArr[$bestRunIndex]['Ir']];
132175
}
133176

134177
/**
135178
* @return array<non-empty-string, numeric-string>
136179
*/
137-
function extractMetricsFromValgrindOutput(string $output): array {
138-
if (!preg_match('/==\d+== Events *:((?: +\w+)+)\n==\d+== Collected :((?: +\d+)+)\n/', $output, $matches)) {
139-
throw new \Exception('Unexpected valgrind output: ' . $output);
180+
function extractMetricsFromCallgrindFile(string $path): array {
181+
if (!preg_match('/\nevents:((?: +\w+)+)\nsummary:((?: +\d+)+)\n/', file_get_contents($path, length: 10_000), $matches)) {
182+
throw new \Exception('Unexpected callgrind data');
140183
}
141184

142185
return array_combine(explode('', ltrim($matches[1], '')), explode('', ltrim($matches[2], '')));

‎sapi/cgi/cgi_main.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,13 +2216,6 @@ consult the installation file that came with this distribution, or visit \n\
22162216
if (comma) {
22172217
warmup_repeats = atoi(php_optarg);
22182218
repeats = atoi(comma + 1);
2219-
#ifdef HAVE_VALGRIND
2220-
if (warmup_repeats > 0) {
2221-
CALLGRIND_STOP_INSTRUMENTATION;
2222-
/* We're not interested in measuring startup */
2223-
CALLGRIND_ZERO_STATS;
2224-
}
2225-
#endif
22262219
} else {
22272220
repeats = atoi(php_optarg);
22282221
}
@@ -2264,6 +2257,13 @@ consult the installation file that came with this distribution, or visit \n\
22642257
}
22652258
#endif
22662259
while (!fastcgi || fcgi_accept_request(request) >= 0) {
2260+
#ifdef HAVE_VALGRIND
2261+
if (benchmark) {
2262+
/* measure startup and each benchmark run separately */
2263+
CALLGRIND_DUMP_STATS;
2264+
}
2265+
#endif
2266+
22672267
SG(server_context) = fastcgi ? (void *)request : (void *) 1;
22682268
init_request_info(request);
22692269

@@ -2430,12 +2430,6 @@ consult the installation file that came with this distribution, or visit \n\
24302430
}
24312431
} /* end !cgi && !fastcgi */
24322432

2433-
#ifdef HAVE_VALGRIND
2434-
if (warmup_repeats == 0) {
2435-
CALLGRIND_START_INSTRUMENTATION;
2436-
}
2437-
#endif
2438-
24392433
/* request startup only after we've done all we can to
24402434
* get path_translated */
24412435
if (php_request_startup() == FAILURE) {
@@ -2554,11 +2548,6 @@ consult the installation file that came with this distribution, or visit \n\
25542548
SG(request_info).query_string = NULL;
25552549
}
25562550

2557-
#ifdef HAVE_VALGRIND
2558-
/* We're not interested in measuring shutdown */
2559-
CALLGRIND_STOP_INSTRUMENTATION;
2560-
#endif
2561-
25622551
if (!fastcgi) {
25632552
if (benchmark) {
25642553
if (warmup_repeats) {
@@ -2586,6 +2575,12 @@ consult the installation file that came with this distribution, or visit \n\
25862575
script_file = NULL;
25872576
goto do_repeat;
25882577
}
2578+
2579+
#ifdef HAVE_VALGRIND
2580+
/* measure shutdown separately */
2581+
CALLGRIND_DUMP_STATS;
2582+
#endif
2583+
25892584
break;
25902585
}
25912586

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /