mirror of
https://github.com/NVIDIA/cuda-samples.git
synced 2026-10-25 22:28:17 +08:00
Apply consistent code formatting across the repo. Add clang-format and pre-commit hooks.
This commit is contained in:
@@ -38,7 +38,7 @@
|
||||
*
|
||||
* Elapsed times are averaged over nreps repetitions (10 by default).
|
||||
*
|
||||
*/
|
||||
*/
|
||||
|
||||
const char *sSDKname = "simpleMultiCopy";
|
||||
|
||||
@@ -50,25 +50,26 @@ const char *sSDKname = "simpleMultiCopy";
|
||||
|
||||
// includes, project
|
||||
#include <helper_cuda.h>
|
||||
#include <helper_functions.h> // helper for shared that are common to CUDA Samples
|
||||
#include <helper_functions.h> // helper for shared that are common to CUDA Samples
|
||||
|
||||
// includes, kernels
|
||||
// Declare the CUDA kernels here and main() code that is needed to launch
|
||||
// Compute workload on the system
|
||||
__global__ void incKernel(int *g_out, int *g_in, int N, int inner_reps) {
|
||||
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
__global__ void incKernel(int *g_out, int *g_in, int N, int inner_reps)
|
||||
{
|
||||
int idx = blockIdx.x * blockDim.x + threadIdx.x;
|
||||
|
||||
if (idx < N) {
|
||||
for (int i = 0; i < inner_reps; ++i) {
|
||||
g_out[idx] = g_in[idx] + 1;
|
||||
if (idx < N) {
|
||||
for (int i = 0; i < inner_reps; ++i) {
|
||||
g_out[idx] = g_in[idx] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define STREAM_COUNT 4
|
||||
|
||||
// Uncomment to simulate data source/sink IO times
|
||||
//#define SIMULATE_IO
|
||||
// #define SIMULATE_IO
|
||||
|
||||
int *h_data_source;
|
||||
int *h_data_sink;
|
||||
@@ -79,13 +80,13 @@ int *d_data_in[STREAM_COUNT];
|
||||
int *h_data_out[STREAM_COUNT];
|
||||
int *d_data_out[STREAM_COUNT];
|
||||
|
||||
cudaEvent_t cycleDone[STREAM_COUNT];
|
||||
cudaEvent_t cycleDone[STREAM_COUNT];
|
||||
cudaStream_t stream[STREAM_COUNT];
|
||||
|
||||
cudaEvent_t start, stop;
|
||||
|
||||
int N = 1 << 22;
|
||||
int nreps = 10; // number of times each experiment is repeated
|
||||
int N = 1 << 22;
|
||||
int nreps = 10; // number of times each experiment is repeated
|
||||
int inner_reps = 5;
|
||||
|
||||
int memsize;
|
||||
@@ -96,278 +97,268 @@ dim3 grid;
|
||||
int thread_blocks;
|
||||
|
||||
float processWithStreams(int streams_used);
|
||||
void init();
|
||||
bool test();
|
||||
void init();
|
||||
bool test();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Program main
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int main(int argc, char *argv[]) {
|
||||
int cuda_device = 0;
|
||||
float scale_factor;
|
||||
cudaDeviceProp deviceProp;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int cuda_device = 0;
|
||||
float scale_factor;
|
||||
cudaDeviceProp deviceProp;
|
||||
|
||||
printf("[%s] - Starting...\n", sSDKname);
|
||||
printf("[%s] - Starting...\n", sSDKname);
|
||||
|
||||
if (checkCmdLineFlag(argc, (const char **)argv, "device")) {
|
||||
cuda_device = getCmdLineArgumentInt(argc, (const char **)argv, "device=");
|
||||
if (checkCmdLineFlag(argc, (const char **)argv, "device")) {
|
||||
cuda_device = getCmdLineArgumentInt(argc, (const char **)argv, "device=");
|
||||
|
||||
if (cuda_device < 0) {
|
||||
printf("Invalid command line parameters\n");
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
printf("cuda_device = %d\n", cuda_device);
|
||||
cuda_device = gpuDeviceInit(cuda_device);
|
||||
if (cuda_device < 0) {
|
||||
printf("Invalid command line parameters\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else {
|
||||
printf("cuda_device = %d\n", cuda_device);
|
||||
cuda_device = gpuDeviceInit(cuda_device);
|
||||
|
||||
if (cuda_device < 0) {
|
||||
printf("No CUDA Capable devices found, exiting...\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
if (cuda_device < 0) {
|
||||
printf("No CUDA Capable devices found, exiting...\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Otherwise pick the device with the highest Gflops/s
|
||||
cuda_device = gpuGetMaxGflopsDeviceId();
|
||||
checkCudaErrors(cudaSetDevice(cuda_device));
|
||||
else {
|
||||
// Otherwise pick the device with the highest Gflops/s
|
||||
cuda_device = gpuGetMaxGflopsDeviceId();
|
||||
checkCudaErrors(cudaSetDevice(cuda_device));
|
||||
checkCudaErrors(cudaGetDeviceProperties(&deviceProp, cuda_device));
|
||||
printf("> Using CUDA device [%d]: %s\n", cuda_device, deviceProp.name);
|
||||
}
|
||||
|
||||
checkCudaErrors(cudaGetDeviceProperties(&deviceProp, cuda_device));
|
||||
printf("> Using CUDA device [%d]: %s\n", cuda_device, deviceProp.name);
|
||||
}
|
||||
printf("[%s] has %d MP(s) x %d (Cores/MP) = %d (Cores)\n",
|
||||
deviceProp.name,
|
||||
deviceProp.multiProcessorCount,
|
||||
_ConvertSMVer2Cores(deviceProp.major, deviceProp.minor),
|
||||
_ConvertSMVer2Cores(deviceProp.major, deviceProp.minor) * deviceProp.multiProcessorCount);
|
||||
|
||||
checkCudaErrors(cudaGetDeviceProperties(&deviceProp, cuda_device));
|
||||
printf("[%s] has %d MP(s) x %d (Cores/MP) = %d (Cores)\n", deviceProp.name,
|
||||
deviceProp.multiProcessorCount,
|
||||
_ConvertSMVer2Cores(deviceProp.major, deviceProp.minor),
|
||||
_ConvertSMVer2Cores(deviceProp.major, deviceProp.minor) *
|
||||
deviceProp.multiProcessorCount);
|
||||
// Anything that is less than 32 Cores will have scaled down workload
|
||||
scale_factor =
|
||||
max((32.0f / (_ConvertSMVer2Cores(deviceProp.major, deviceProp.minor) * (float)deviceProp.multiProcessorCount)),
|
||||
1.0f);
|
||||
N = (int)((float)N / scale_factor);
|
||||
|
||||
// Anything that is less than 32 Cores will have scaled down workload
|
||||
scale_factor =
|
||||
max((32.0f / (_ConvertSMVer2Cores(deviceProp.major, deviceProp.minor) *
|
||||
(float)deviceProp.multiProcessorCount)),
|
||||
1.0f);
|
||||
N = (int)((float)N / scale_factor);
|
||||
printf("> Device name: %s\n", deviceProp.name);
|
||||
printf("> CUDA Capability %d.%d hardware with %d multi-processors\n",
|
||||
deviceProp.major,
|
||||
deviceProp.minor,
|
||||
deviceProp.multiProcessorCount);
|
||||
printf("> scale_factor = %.2f\n", 1.0f / scale_factor);
|
||||
printf("> array_size = %d\n\n", N);
|
||||
|
||||
printf("> Device name: %s\n", deviceProp.name);
|
||||
printf("> CUDA Capability %d.%d hardware with %d multi-processors\n",
|
||||
deviceProp.major, deviceProp.minor, deviceProp.multiProcessorCount);
|
||||
printf("> scale_factor = %.2f\n", 1.0f / scale_factor);
|
||||
printf("> array_size = %d\n\n", N);
|
||||
memsize = N * sizeof(int);
|
||||
|
||||
memsize = N * sizeof(int);
|
||||
thread_blocks = N / block.x;
|
||||
|
||||
thread_blocks = N / block.x;
|
||||
grid.x = thread_blocks % 65535;
|
||||
grid.y = (thread_blocks / 65535 + 1);
|
||||
|
||||
grid.x = thread_blocks % 65535;
|
||||
grid.y = (thread_blocks / 65535 + 1);
|
||||
// Allocate resources
|
||||
|
||||
// Allocate resources
|
||||
h_data_source = (int *)malloc(memsize);
|
||||
h_data_sink = (int *)malloc(memsize);
|
||||
|
||||
h_data_source = (int *)malloc(memsize);
|
||||
h_data_sink = (int *)malloc(memsize);
|
||||
for (int i = 0; i < STREAM_COUNT; ++i) {
|
||||
checkCudaErrors(cudaHostAlloc(&h_data_in[i], memsize, cudaHostAllocDefault));
|
||||
checkCudaErrors(cudaMalloc(&d_data_in[i], memsize));
|
||||
checkCudaErrors(cudaMemset(d_data_in[i], 0, memsize));
|
||||
|
||||
for (int i = 0; i < STREAM_COUNT; ++i) {
|
||||
checkCudaErrors(
|
||||
cudaHostAlloc(&h_data_in[i], memsize, cudaHostAllocDefault));
|
||||
checkCudaErrors(cudaMalloc(&d_data_in[i], memsize));
|
||||
checkCudaErrors(cudaMemset(d_data_in[i], 0, memsize));
|
||||
checkCudaErrors(cudaHostAlloc(&h_data_out[i], memsize, cudaHostAllocDefault));
|
||||
checkCudaErrors(cudaMalloc(&d_data_out[i], memsize));
|
||||
|
||||
checkCudaErrors(
|
||||
cudaHostAlloc(&h_data_out[i], memsize, cudaHostAllocDefault));
|
||||
checkCudaErrors(cudaMalloc(&d_data_out[i], memsize));
|
||||
checkCudaErrors(cudaStreamCreate(&stream[i]));
|
||||
checkCudaErrors(cudaEventCreate(&cycleDone[i]));
|
||||
|
||||
checkCudaErrors(cudaStreamCreate(&stream[i]));
|
||||
checkCudaErrors(cudaEventCreate(&cycleDone[i]));
|
||||
cudaEventRecord(cycleDone[i], stream[i]);
|
||||
}
|
||||
|
||||
cudaEventRecord(cycleDone[i], stream[i]);
|
||||
}
|
||||
cudaEventCreate(&start);
|
||||
cudaEventCreate(&stop);
|
||||
|
||||
cudaEventCreate(&start);
|
||||
cudaEventCreate(&stop);
|
||||
init();
|
||||
|
||||
init();
|
||||
// Kernel warmup
|
||||
incKernel<<<grid, block>>>(d_data_out[0], d_data_in[0], N, inner_reps);
|
||||
|
||||
// Kernel warmup
|
||||
incKernel<<<grid, block>>>(d_data_out[0], d_data_in[0], N, inner_reps);
|
||||
// Time copies and kernel
|
||||
cudaEventRecord(start, 0);
|
||||
checkCudaErrors(cudaMemcpyAsync(d_data_in[0], h_data_in[0], memsize, cudaMemcpyHostToDevice, 0));
|
||||
cudaEventRecord(stop, 0);
|
||||
cudaEventSynchronize(stop);
|
||||
|
||||
// Time copies and kernel
|
||||
cudaEventRecord(start, 0);
|
||||
checkCudaErrors(cudaMemcpyAsync(d_data_in[0], h_data_in[0], memsize,
|
||||
cudaMemcpyHostToDevice, 0));
|
||||
cudaEventRecord(stop, 0);
|
||||
cudaEventSynchronize(stop);
|
||||
float memcpy_h2d_time;
|
||||
cudaEventElapsedTime(&memcpy_h2d_time, start, stop);
|
||||
|
||||
float memcpy_h2d_time;
|
||||
cudaEventElapsedTime(&memcpy_h2d_time, start, stop);
|
||||
cudaEventRecord(start, 0);
|
||||
checkCudaErrors(cudaMemcpyAsync(h_data_out[0], d_data_out[0], memsize, cudaMemcpyDeviceToHost, 0));
|
||||
cudaEventRecord(stop, 0);
|
||||
cudaEventSynchronize(stop);
|
||||
|
||||
cudaEventRecord(start, 0);
|
||||
checkCudaErrors(cudaMemcpyAsync(h_data_out[0], d_data_out[0], memsize,
|
||||
cudaMemcpyDeviceToHost, 0));
|
||||
cudaEventRecord(stop, 0);
|
||||
cudaEventSynchronize(stop);
|
||||
float memcpy_d2h_time;
|
||||
cudaEventElapsedTime(&memcpy_d2h_time, start, stop);
|
||||
|
||||
float memcpy_d2h_time;
|
||||
cudaEventElapsedTime(&memcpy_d2h_time, start, stop);
|
||||
cudaEventRecord(start, 0);
|
||||
incKernel<<<grid, block, 0, 0>>>(d_data_out[0], d_data_in[0], N, inner_reps);
|
||||
cudaEventRecord(stop, 0);
|
||||
cudaEventSynchronize(stop);
|
||||
|
||||
cudaEventRecord(start, 0);
|
||||
incKernel<<<grid, block, 0, 0>>>(d_data_out[0], d_data_in[0], N, inner_reps);
|
||||
cudaEventRecord(stop, 0);
|
||||
cudaEventSynchronize(stop);
|
||||
float kernel_time;
|
||||
cudaEventElapsedTime(&kernel_time, start, stop);
|
||||
|
||||
float kernel_time;
|
||||
cudaEventElapsedTime(&kernel_time, start, stop);
|
||||
printf("\n");
|
||||
printf("Relevant properties of this CUDA device\n");
|
||||
printf("(%s) Can overlap one CPU<>GPU data transfer with GPU kernel execution "
|
||||
"(device property \"deviceOverlap\")\n",
|
||||
deviceProp.deviceOverlap ? "X" : " ");
|
||||
// printf("(%s) Can execute several GPU kernels simultaneously (compute
|
||||
// capability >= 2.0)\n", deviceProp.major >= 2 ? "X": " ");
|
||||
printf("(%s) Can overlap two CPU<>GPU data transfers with GPU kernel execution\n"
|
||||
" (Compute Capability >= 2.0 AND (Tesla product OR Quadro "
|
||||
"4000/5000/6000/K5000)\n",
|
||||
(deviceProp.major >= 2 && deviceProp.asyncEngineCount > 1) ? "X" : " ");
|
||||
|
||||
printf("\n");
|
||||
printf("Relevant properties of this CUDA device\n");
|
||||
printf(
|
||||
"(%s) Can overlap one CPU<>GPU data transfer with GPU kernel execution "
|
||||
"(device property \"deviceOverlap\")\n",
|
||||
deviceProp.deviceOverlap ? "X" : " ");
|
||||
// printf("(%s) Can execute several GPU kernels simultaneously (compute
|
||||
// capability >= 2.0)\n", deviceProp.major >= 2 ? "X": " ");
|
||||
printf(
|
||||
"(%s) Can overlap two CPU<>GPU data transfers with GPU kernel execution\n"
|
||||
" (Compute Capability >= 2.0 AND (Tesla product OR Quadro "
|
||||
"4000/5000/6000/K5000)\n",
|
||||
(deviceProp.major >= 2 && deviceProp.asyncEngineCount > 1) ? "X" : " ");
|
||||
printf("\n");
|
||||
printf("Measured timings (throughput):\n");
|
||||
printf(" Memcpy host to device\t: %f ms (%f GB/s)\n", memcpy_h2d_time, (memsize * 1e-6) / memcpy_h2d_time);
|
||||
printf(" Memcpy device to host\t: %f ms (%f GB/s)\n", memcpy_d2h_time, (memsize * 1e-6) / memcpy_d2h_time);
|
||||
printf(" Kernel\t\t\t: %f ms (%f GB/s)\n", kernel_time, (inner_reps * memsize * 2e-6) / kernel_time);
|
||||
|
||||
printf("\n");
|
||||
printf("Measured timings (throughput):\n");
|
||||
printf(" Memcpy host to device\t: %f ms (%f GB/s)\n", memcpy_h2d_time,
|
||||
(memsize * 1e-6) / memcpy_h2d_time);
|
||||
printf(" Memcpy device to host\t: %f ms (%f GB/s)\n", memcpy_d2h_time,
|
||||
(memsize * 1e-6) / memcpy_d2h_time);
|
||||
printf(" Kernel\t\t\t: %f ms (%f GB/s)\n", kernel_time,
|
||||
(inner_reps * memsize * 2e-6) / kernel_time);
|
||||
printf("\n");
|
||||
printf("Theoretical limits for speedup gained from overlapped data "
|
||||
"transfers:\n");
|
||||
printf("No overlap at all (transfer-kernel-transfer): %f ms \n", memcpy_h2d_time + memcpy_d2h_time + kernel_time);
|
||||
printf("Compute can overlap with one transfer: %f ms\n", max((memcpy_h2d_time + memcpy_d2h_time), kernel_time));
|
||||
printf("Compute can overlap with both data transfers: %f ms\n",
|
||||
max(max(memcpy_h2d_time, memcpy_d2h_time), kernel_time));
|
||||
|
||||
printf("\n");
|
||||
printf(
|
||||
"Theoretical limits for speedup gained from overlapped data "
|
||||
"transfers:\n");
|
||||
printf("No overlap at all (transfer-kernel-transfer): %f ms \n",
|
||||
memcpy_h2d_time + memcpy_d2h_time + kernel_time);
|
||||
printf("Compute can overlap with one transfer: %f ms\n",
|
||||
max((memcpy_h2d_time + memcpy_d2h_time), kernel_time));
|
||||
printf("Compute can overlap with both data transfers: %f ms\n",
|
||||
max(max(memcpy_h2d_time, memcpy_d2h_time), kernel_time));
|
||||
// Process pipelined work
|
||||
float serial_time = processWithStreams(1);
|
||||
float overlap_time = processWithStreams(STREAM_COUNT);
|
||||
|
||||
// Process pipelined work
|
||||
float serial_time = processWithStreams(1);
|
||||
float overlap_time = processWithStreams(STREAM_COUNT);
|
||||
printf("\nAverage measured timings over %d repetitions:\n", nreps);
|
||||
printf(" Avg. time when execution fully serialized\t: %f ms\n", serial_time / nreps);
|
||||
printf(" Avg. time when overlapped using %d streams\t: %f ms\n", STREAM_COUNT, overlap_time / nreps);
|
||||
printf(" Avg. speedup gained (serialized - overlapped)\t: %f ms\n", (serial_time - overlap_time) / nreps);
|
||||
|
||||
printf("\nAverage measured timings over %d repetitions:\n", nreps);
|
||||
printf(" Avg. time when execution fully serialized\t: %f ms\n",
|
||||
serial_time / nreps);
|
||||
printf(" Avg. time when overlapped using %d streams\t: %f ms\n", STREAM_COUNT,
|
||||
overlap_time / nreps);
|
||||
printf(" Avg. speedup gained (serialized - overlapped)\t: %f ms\n",
|
||||
(serial_time - overlap_time) / nreps);
|
||||
printf("\nMeasured throughput:\n");
|
||||
printf(" Fully serialized execution\t\t: %f GB/s\n", (nreps * (memsize * 2e-6)) / serial_time);
|
||||
printf(" Overlapped using %d streams\t\t: %f GB/s\n", STREAM_COUNT, (nreps * (memsize * 2e-6)) / overlap_time);
|
||||
|
||||
printf("\nMeasured throughput:\n");
|
||||
printf(" Fully serialized execution\t\t: %f GB/s\n",
|
||||
(nreps * (memsize * 2e-6)) / serial_time);
|
||||
printf(" Overlapped using %d streams\t\t: %f GB/s\n", STREAM_COUNT,
|
||||
(nreps * (memsize * 2e-6)) / overlap_time);
|
||||
// Verify the results, we will use the results for final output
|
||||
bool bResults = test();
|
||||
|
||||
// Verify the results, we will use the results for final output
|
||||
bool bResults = test();
|
||||
// Free resources
|
||||
|
||||
// Free resources
|
||||
free(h_data_source);
|
||||
free(h_data_sink);
|
||||
|
||||
free(h_data_source);
|
||||
free(h_data_sink);
|
||||
for (int i = 0; i < STREAM_COUNT; ++i) {
|
||||
cudaFreeHost(h_data_in[i]);
|
||||
cudaFree(d_data_in[i]);
|
||||
|
||||
for (int i = 0; i < STREAM_COUNT; ++i) {
|
||||
cudaFreeHost(h_data_in[i]);
|
||||
cudaFree(d_data_in[i]);
|
||||
cudaFreeHost(h_data_out[i]);
|
||||
cudaFree(d_data_out[i]);
|
||||
|
||||
cudaFreeHost(h_data_out[i]);
|
||||
cudaFree(d_data_out[i]);
|
||||
cudaStreamDestroy(stream[i]);
|
||||
cudaEventDestroy(cycleDone[i]);
|
||||
}
|
||||
|
||||
cudaStreamDestroy(stream[i]);
|
||||
cudaEventDestroy(cycleDone[i]);
|
||||
}
|
||||
cudaEventDestroy(start);
|
||||
cudaEventDestroy(stop);
|
||||
|
||||
cudaEventDestroy(start);
|
||||
cudaEventDestroy(stop);
|
||||
|
||||
// Test result
|
||||
exit(bResults ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
// Test result
|
||||
exit(bResults ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||
}
|
||||
|
||||
float processWithStreams(int streams_used) {
|
||||
int current_stream = 0;
|
||||
float processWithStreams(int streams_used)
|
||||
{
|
||||
int current_stream = 0;
|
||||
|
||||
float time;
|
||||
float time;
|
||||
|
||||
// Do processing in a loop
|
||||
//
|
||||
// Note: All memory commands are processed in the order they are issued,
|
||||
// independent of the stream they are enqueued in. Hence the pattern by
|
||||
// which the copy and kernel commands are enqueued in the stream
|
||||
// has an influence on the achieved overlap.
|
||||
// Do processing in a loop
|
||||
//
|
||||
// Note: All memory commands are processed in the order they are issued,
|
||||
// independent of the stream they are enqueued in. Hence the pattern by
|
||||
// which the copy and kernel commands are enqueued in the stream
|
||||
// has an influence on the achieved overlap.
|
||||
|
||||
cudaEventRecord(start, 0);
|
||||
cudaEventRecord(start, 0);
|
||||
|
||||
for (int i = 0; i < nreps; ++i) {
|
||||
int next_stream = (current_stream + 1) % streams_used;
|
||||
for (int i = 0; i < nreps; ++i) {
|
||||
int next_stream = (current_stream + 1) % streams_used;
|
||||
|
||||
#ifdef SIMULATE_IO
|
||||
// Store the result
|
||||
memcpy(h_data_sink, h_data_out[current_stream], memsize);
|
||||
// Store the result
|
||||
memcpy(h_data_sink, h_data_out[current_stream], memsize);
|
||||
|
||||
// Read new input
|
||||
memcpy(h_data_in[next_stream], h_data_source, memsize);
|
||||
// Read new input
|
||||
memcpy(h_data_in[next_stream], h_data_source, memsize);
|
||||
#endif
|
||||
|
||||
// Ensure that processing and copying of the last cycle has finished
|
||||
cudaEventSynchronize(cycleDone[next_stream]);
|
||||
// Ensure that processing and copying of the last cycle has finished
|
||||
cudaEventSynchronize(cycleDone[next_stream]);
|
||||
|
||||
// Process current frame
|
||||
incKernel<<<grid, block, 0, stream[current_stream]>>>(
|
||||
d_data_out[current_stream], d_data_in[current_stream], N, inner_reps);
|
||||
// Process current frame
|
||||
incKernel<<<grid, block, 0, stream[current_stream]>>>(
|
||||
d_data_out[current_stream], d_data_in[current_stream], N, inner_reps);
|
||||
|
||||
// Upload next frame
|
||||
checkCudaErrors(
|
||||
cudaMemcpyAsync(d_data_in[next_stream], h_data_in[next_stream], memsize,
|
||||
cudaMemcpyHostToDevice, stream[next_stream]));
|
||||
// Upload next frame
|
||||
checkCudaErrors(cudaMemcpyAsync(
|
||||
d_data_in[next_stream], h_data_in[next_stream], memsize, cudaMemcpyHostToDevice, stream[next_stream]));
|
||||
|
||||
// Download current frame
|
||||
checkCudaErrors(cudaMemcpyAsync(
|
||||
h_data_out[current_stream], d_data_out[current_stream], memsize,
|
||||
cudaMemcpyDeviceToHost, stream[current_stream]));
|
||||
// Download current frame
|
||||
checkCudaErrors(cudaMemcpyAsync(h_data_out[current_stream],
|
||||
d_data_out[current_stream],
|
||||
memsize,
|
||||
cudaMemcpyDeviceToHost,
|
||||
stream[current_stream]));
|
||||
|
||||
checkCudaErrors(
|
||||
cudaEventRecord(cycleDone[current_stream], stream[current_stream]));
|
||||
checkCudaErrors(cudaEventRecord(cycleDone[current_stream], stream[current_stream]));
|
||||
|
||||
current_stream = next_stream;
|
||||
}
|
||||
|
||||
cudaEventRecord(stop, 0);
|
||||
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
cudaEventElapsedTime(&time, start, stop);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
void init() {
|
||||
for (int i = 0; i < N; ++i) {
|
||||
h_data_source[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < STREAM_COUNT; ++i) {
|
||||
memcpy(h_data_in[i], h_data_source, memsize);
|
||||
}
|
||||
}
|
||||
|
||||
bool test() {
|
||||
bool passed = true;
|
||||
|
||||
for (int j = 0; j < STREAM_COUNT; ++j) {
|
||||
for (int i = 0; i < N; ++i) {
|
||||
passed &= (h_data_out[j][i] == 1);
|
||||
current_stream = next_stream;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
cudaEventRecord(stop, 0);
|
||||
|
||||
cudaDeviceSynchronize();
|
||||
|
||||
cudaEventElapsedTime(&time, start, stop);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
for (int i = 0; i < N; ++i) {
|
||||
h_data_source[i] = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < STREAM_COUNT; ++i) {
|
||||
memcpy(h_data_in[i], h_data_source, memsize);
|
||||
}
|
||||
}
|
||||
|
||||
bool test()
|
||||
{
|
||||
bool passed = true;
|
||||
|
||||
for (int j = 0; j < STREAM_COUNT; ++j) {
|
||||
for (int i = 0; i < N; ++i) {
|
||||
passed &= (h_data_out[j][i] == 1);
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user