3
运行时
测试同一流内不同命令的运行时间
2022-11-09 10:38:25
45

同一个流内顺序执行以下命令:(1)主机到内存设备拷贝;(2)内核函数;(3)设备到主机内存拷贝。分别在不同命令执行前和执行后压入一个事件记录时间。
我自己在GPU上用cuda平台执行的时候,3个命令的执行时间加起来刚好等于总的运行时间。
在DCU上,就出现了问题,3个命令执行时间加起来不是总的运行时间。不知道是什么原因。
代码如下:

#include <iostream>
#include "hip/hip_runtime.h"
#include <hip/hip_runtime.h>

void initialData(float * v, int size)
{
for(int i = 0; i < size; i++)
v[i] = i;
}

global void add(float *d_A, float *d_B, float *d_C, int N)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
if (tid < N)
{
d_C[tid] = d_A[tid] * sin(d_B[tid]);
}
}

int main(int argc, char **argv)
{
int ndcus;
hipGetDeviceCount(&ndcus);
printf("HIP-capable devices: %i\n", ndcus);

float *d_A[ndcus], *d_B[ndcus], *d_C[ndcus]; //设备内存

float *h_A[ndcus], *h_B[ndcus], *dcuRef[ndcus];	 //主机内存

hipStream_t stream[ndcus];

//平均分配到各个设备上
int size = 1 << 26;
int iSize = size / ndcus;

std::cout << "个数" << iSize << std::endl;

size_t iBytes = iSize * sizeof(float);

std::cout << "内存大小" << iBytes << std::endl;

//分配主机和设备内存
for (int i = 0; i < ndcus; i++)
{
	// 设置DCU
	hipSetDevice(i);

	// 分配设备内存
	hipMalloc((void **) &d_A[i], iBytes);
	hipMalloc((void **) &d_B[i], iBytes);
	hipMalloc((void **) &d_C[i], iBytes);

	//分配锁页主机内存
	hipHostMalloc((void **) &h_A[i], iBytes);
	hipHostMalloc((void **) &h_B[i], iBytes);
	hipHostMalloc((void **) &dcuRef[i], iBytes);

	// 创建流对象
	hipStreamCreate(&stream[i]);
}

//数据初始化
for (int i = 0; i < ndcus; i++) {
	hipSetDevice(i);
	initialData(h_A[i], iSize);
	initialData(h_B[i], iSize);
}

//for(int i =0; i < ndcus; i++)
//for(int j= 0; j < 5; j++)
// std::cout << h_A[i][j]<< " " << h_B[i][j]<< std::endl;

hipEvent_t memcpy_to_start_event[ndcus];
hipEvent_t kernel_start_event[ndcus];
hipEvent_t memcpy_from_start_event[ndcus]; 
hipEvent_t memcpy_from_stop_event[ndcus]; 

dim3 block(256, 1);
dim3 grid(iSize / 256 + 1, 1);

float time_copy_to_ms = 0.0f;  
float time_kernel_ms = 0.0f; 
float time_copy_from_ms = 0.0f;  
float time_exec_ms = 0.0f;  
  

for(int i = 0; i < ndcus; i++) 
{
	hipSetDevice(i);
  
 hipEventCreate(&memcpy_to_start_event[i]);
 hipEventCreate(&kernel_start_event[i]);
 hipEventCreate(& memcpy_from_start_event[i]);
 hipEventCreate(& memcpy_from_stop_event[i]);
 
  
hipEventRecord(memcpy_to_start_event[i], stream[i]);

//主机拷入设备1
hipMemcpyAsync(d_A[i], h_A[i], iBytes, hipMemcpyHostToDevice, stream[i]);
hipMemcpyAsync(d_B[i], h_B[i],  iBytes, hipMemcpyHostToDevice, stream[i]);

hipEventRecord(kernel_start_event[i], stream[i]);

 
//内核函数
hipLaunchKernelGGL(add, grid, block, 0, stream[i], d_A[i], d_B[i], d_C[i], iSize); 

hipEventRecord(memcpy_from_start_event[i], stream[i]);

//设备考入主机
hipMemcpyAsync(dcuRef[i], d_C[i], iBytes, hipMemcpyDeviceToHost, stream[i]);  

hipEventRecord(memcpy_from_stop_event[i], stream[i]); 
     
}

for(int i = 0; i < ndcus; i++) 
{
   //hipSetDevice(i);
   hipStreamSynchronize(stream[i]);
   
      //内存从设备到主机的拷贝时间

   hipEventElapsedTime(&time_copy_to_ms, memcpy_to_start_event[i], kernel_start_event[i]);
   
   //内存从主机到设备的拷贝时间
   hipEventElapsedTime(&time_kernel_ms, kernel_start_event[i], memcpy_from_start_event[i]);
   
   //内存从设备到主机的拷贝时间
   hipEventElapsedTime(&time_copy_from_ms, memcpy_from_start_event[i],  memcpy_from_stop_event[i]);
   
    //总执行时间
   hipEventElapsedTime(& time_exec_ms, memcpy_to_start_event[i], memcpy_from_stop_event[i]);
 
 float gpu_time = time_copy_to_ms + time_kernel_ms + time_copy_from_ms  ;
 
   std::cout << "device" << i << std::endl;
   std::cout << "Copy to: " << time_copy_to_ms << std::endl;
   std::cout << "Kernel: " << time_kernel_ms << std::endl;
   std::cout << "Copy back: " << time_copy_from_ms << std::endl;
   std::cout << "Component time: " << gpu_time << std::endl;
   std::cout << "Execution time: " << time_exec_ms << std::endl;

   
  std::cout <<  std::endl;   
 }

//等所有设备完毕
hipDeviceSynchronize();

//测试结果
for(int i = 0; i < ndcus; i++)
{
	for(int j = 0; j < 10; j++)
	   std::cout << dcuRef[i][j] << std::endl;


	std::cout << std::endl;
}

//释放内存
std::cout << "释放内存";
for(int i = 0; i < ndcus; i++)
{
	hipFree(d_A[i]);
	hipFree(d_B[i]);
	hipFree(d_C[i]);

	hipHostFree(h_A[i]);
	hipHostFree(h_B[i]);
	hipHostFree(dcuRef[i]);
  
    hipEventDestroy( memcpy_to_start_event[i]);
    hipEventDestroy( kernel_start_event[i]);
     hipEventDestroy( memcpy_from_start_event[i]);
     hipEventDestroy(memcpy_from_stop_event[i]);

}


return 0;

}

全部评论(1)
只看楼主
T
tianlh
1楼
您好,经复现分析,这种现象跟HIP技术处理命令方式有关。合并执行时各步之间有间隙,不如CUDA处理紧凑,建议使用hipprof详细看下合并执行时的耗时情况。
2022/11/9
没有更多内容了
--
楼主
Level.4
0 帖子
楼主热帖
暂无数据