summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--measure_launch_oh.cu17
1 files changed, 14 insertions, 3 deletions
diff --git a/measure_launch_oh.cu b/measure_launch_oh.cu
index 981448a..0a253a2 100644
--- a/measure_launch_oh.cu
+++ b/measure_launch_oh.cu
@@ -1,8 +1,11 @@
1/* Copyright 2024 Joshua Bakita 1/* Copyright 2024 Joshua Bakita
2 * Simple kernel that clocks how long a kernel launch takes to the GPU. 2 * Simple kernel that clocks how long a kernel launch takes to the GPU.
3 * Prints samples to stdout and summary statistics to stderr. 3 * Prints samples to stdout and summary statistics to stderr.
4 *
5 * For best results, pin to a CPU core and redirect interrupts.
4 */ 6 */
5#include <time.h> 7#include <time.h>
8#include <sched.h>
6#include <stdio.h> 9#include <stdio.h>
7#include <stdint.h> 10#include <stdint.h>
8#include <unistd.h> 11#include <unistd.h>
@@ -14,7 +17,7 @@ __global__ void flag_on_gpu(volatile int *flag) {
14} 17}
15 18
16// Get launch overhead 19// Get launch overhead
17long measure_launch_overhead() { 20long measure_launch_overhead(bool first_run) {
18 volatile int *barrier; 21 volatile int *barrier;
19 struct timespec start, end; 22 struct timespec start, end;
20 SAFE(cudaHostAlloc(&barrier, sizeof(*barrier), cudaHostAllocMapped)); 23 SAFE(cudaHostAlloc(&barrier, sizeof(*barrier), cudaHostAllocMapped));
@@ -24,6 +27,9 @@ long measure_launch_overhead() {
24 while (!*barrier) continue; 27 while (!*barrier) continue;
25 clock_gettime(CLOCK_MONOTONIC_RAW, &end); 28 clock_gettime(CLOCK_MONOTONIC_RAW, &end);
26 SAFE(cudaDeviceSynchronize()); 29 SAFE(cudaDeviceSynchronize());
30 if (first_run)
31 fprintf(stderr, "(%d) First launch completed at CLOCK_MONOTONIC_RAW = %ld ns\n",
32 getpid(), time2ns(end));
27 return timediff(start, end); 33 return timediff(start, end);
28} 34}
29 35
@@ -44,13 +50,18 @@ int main(int argc, char **argv) {
44 SAFE(cudaMalloc(&__unused, 8)); 50 SAFE(cudaMalloc(&__unused, 8));
45 51
46 // Run once to ensure the kernel is compiled 52 // Run once to ensure the kernel is compiled
47 time = measure_launch_overhead(); 53 time = measure_launch_overhead(true);
48 fprintf(stderr, "(%d) %ld ns (%.2f ms) warmup launch overhead\n", getpid(), 54 fprintf(stderr, "(%d) %ld ns (%.2f ms) warmup launch overhead\n", getpid(),
49 time, ns2ms((double)time)); 55 time, ns2ms((double)time));
50 56
51 // Time several kernel launches 57 // Time several kernel launches
52 for (i = 0; i < num_iters; i++) { 58 for (i = 0; i < num_iters; i++) {
53 time = measure_launch_overhead(); 59 // We're measuring on the order of microseconds. Make sure the
60 // kernel scheduler does not interrupt us during a timing
61 // iteration by explicitly invoking it here.
62 sched_yield();
63 // Measure overhead
64 time = measure_launch_overhead(false);
54 cumulative_time += time; 65 cumulative_time += time;
55 // Print one sample per line 66 // Print one sample per line
56 fprintf(stdout, "%ld\n", time); 67 fprintf(stdout, "%ld\n", time);