首页 > 其他分享 >GPU CPU向量加法时间测试

GPU CPU向量加法时间测试

时间:2022-12-11 20:59:07浏览次数:42  
标签:int res float tm sec 加法 GPU CPU

GPU CPU向量加法时间测试

实验设备

系统:WSL Ubuntu18.04

image-20221211200048837

实验思路

分别在GPU,CPU上测试两个一维向量的加法,CPU是一个个的串行计算相加,GPU可以通过并行的方式将对应位置的元素相加。

实验结果

向量a,b的维度 262144\((512 \times 512)\) 1048576\((1024 \times 1024)\) 4194304\((2048 \times 2048)\)
实验结果截图 image-20221211200914984 image-20221211201005834 image-20221211201032021
内存数据拷贝到GPU时间消耗 0.000754 sec 0.001460 sec 0.004343sec
GPU计算时间 0.000021 sec 0.000026 sec 0.000028 sec
结果从显存拷贝到内存时间消耗 0.000263sec 0.000954 sec 0.002438 sec
CPU 计算时间 0.000372 sec 0.001884 sec 0.006497 sec

分析:

  1. 对比GPU和CPU的计算时间,随着数据维度增大,GPU计算时间没有明显的增大,CPU计算时间逐渐增大。
  2. 随着数据维度增大,数据在内存到显存双向拷贝时间逐渐增大。
  3. 数据拷贝的时间+GPU计算时间(前三行),并没有使得向量加法的运行效率提高,这还有待研究

实验代码

sum.cu

#include <cuda_runtime.h>
#include <stdio.h>
#include "freshman.h"


// CPU 加法
void sumArrays(float *a, float *b, float *res, const int size)
{
  for (int i = 0; i < size; i += 1)
  {
    res[i] = a[i] + b[i];
  }
}

// GPU 加法
__global__ void sumArraysGPU(float *a, float *b, float *res, int N)
{
  int i = blockIdx.x * blockDim.x + threadIdx.x;
  if (i < N)
    res[i] = a[i] + b[i];
}

int main(int argc, char **argv)
{
  // set up device
  initDevice(0);

  int nElem = 512*512;
  // int nElem = 1024*1024;
  // int nElem = 2048*2048;

  printf("Vector size:%d\n", nElem);

  // 内存数据申请空间
  int nByte = sizeof(float) * nElem;
  float *a_h = (float *)malloc(nByte);
  float *b_h = (float *)malloc(nByte);
  float *res_h = (float *)malloc(nByte);
  float *res_from_gpu_h = (float *)malloc(nByte);
  memset(res_h, 0, nByte);
  memset(res_from_gpu_h, 0, nByte);

  // 内存数据随机初始化
  initialData(a_h, nElem);
  initialData(b_h, nElem);

  // 显存申请空间
  float *a_d, *b_d, *res_d;
  CHECK(cudaMalloc((float **)&a_d, nByte));
  CHECK(cudaMalloc((float **)&b_d, nByte));
  CHECK(cudaMalloc((float **)&res_d, nByte));


  // 内存到显存数据拷贝
  double iStart, iElaps;
  iStart = cpuSecond();
  CHECK(cudaMemcpy(a_d, a_h, nByte, cudaMemcpyHostToDevice));
  CHECK(cudaMemcpy(b_d, b_h, nByte, cudaMemcpyHostToDevice));
  iElaps = cpuSecond() - iStart;
  printf("内存数据拷贝到GPU时间消耗\t%f sec\n",  iElaps);

  dim3 block(512);
  dim3 grid((nElem - 1) / block.x + 1);

  // GPU 加法
  iStart = cpuSecond();
  sumArraysGPU<<<grid, block>>>(a_d, b_d, res_d, nElem);
  iElaps = cpuSecond() - iStart;
  printf("GPU计算时间 \t\t\t\t %f sec\n", iElaps);

  //显存到内存数据拷贝
  iStart = cpuSecond();
  CHECK(cudaMemcpy(res_from_gpu_h, res_d, nByte, cudaMemcpyDeviceToHost));
  iElaps = cpuSecond() - iStart;
  printf("结果从显存拷贝到内存时间消耗   %f sec\n",  iElaps);

  // CPU 加法
  iStart = cpuSecond();
  sumArrays(a_h,b_h,res_h,nElem);
  iElaps= cpuSecond() - iStart;
  printf("CPU 计算时间\t\t\t\t %f sec\n", iElaps);

  checkResult(res_h, res_from_gpu_h, nElem);
  cudaFree(a_d);
  cudaFree(b_d);
  cudaFree(res_d);

  free(a_h);
  free(b_h);
  free(res_h);
  free(res_from_gpu_h);

  return 0;
}

freshman.h

#ifndef FRESHMAN_H
#define FRESHMAN_H
#define CHECK(call)\
{\
  const cudaError_t error=call;\
  if(error!=cudaSuccess)\
  {\
      printf("ERROR: %s:%d,",__FILE__,__LINE__);\
      printf("code:%d,reason:%s\n",error,cudaGetErrorString(error));\
      exit(1);\
  }\
}


#include <time.h>
#ifdef _WIN32
#	include <windows.h>
#else
#	include <sys/time.h>
#endif
#ifdef _WIN32
int gettimeofday(struct timeval *tp, void *tzp)
{
  time_t clock;
  struct tm tm;
  SYSTEMTIME wtm;
  GetLocalTime(&wtm);
  tm.tm_year   = wtm.wYear - 1900;
  tm.tm_mon   = wtm.wMonth - 1;
  tm.tm_mday   = wtm.wDay;
  tm.tm_hour   = wtm.wHour;
  tm.tm_min   = wtm.wMinute;
  tm.tm_sec   = wtm.wSecond;
  tm. tm_isdst  = -1;
  clock = mktime(&tm);
  tp->tv_sec = clock;
  tp->tv_usec = wtm.wMilliseconds * 1000;
  return (0);
}
#endif
double cpuSecond()
{
  struct timeval tp;
  gettimeofday(&tp,NULL);
  return((double)tp.tv_sec+(double)tp.tv_usec*1e-6);

}
void initialData(float* ip,int size)
{
  time_t t;
  srand((unsigned )time(&t));
  for(int i=0;i<size;i++)
  {
    ip[i]=(float)(rand()&0xffff)/1000.0f;
  }
}
void initialData_int(int* ip, int size)
{
	time_t t;
	srand((unsigned)time(&t));
	for (int i = 0; i<size; i++)
	{
		ip[i] = int(rand()&0xff);
	}
}
void printMatrix(float * C,const int nx,const int ny)
{
  float *ic=C;
  printf("Matrix<%d,%d>:",ny,nx);
  for(int i=0;i<ny;i++)
  {
    for(int j=0;j<nx;j++)
    {
      printf("%6f ",C[j]);
    }
    ic+=nx;
    printf("\n");
  }
}

void initDevice(int devNum)
{
  int dev = devNum;
  cudaDeviceProp deviceProp;
  CHECK(cudaGetDeviceProperties(&deviceProp,dev));
  printf("Using device %d: %s\n",dev,deviceProp.name);
  CHECK(cudaSetDevice(dev));

}
void checkResult(float * hostRef,float * gpuRef,const int N)
{
  double epsilon=1.0E-8;
  for(int i=0;i<N;i++)
  {
    if(abs(hostRef[i]-gpuRef[i])>epsilon)
    {
      printf("Results don\'t match!\n");
      printf("%f(hostRef[%d] )!= %f(gpuRef[%d])\n",hostRef[i],i,gpuRef[i],i);
      return;
    }
  }
  printf("Check result success!\n");
}
#endif//FRESHMAN_H

标签:int,res,float,tm,sec,加法,GPU,CPU
From: https://www.cnblogs.com/programmerwang/p/16974393.html

相关文章

  • 指定GPU运行和训练python程序 、深度学习单卡、多卡 训练GPU设置【一文读懂】
    版权:本文由【墨理学AI】原创、各位大佬、一文读懂、敬请查阅声明:作为全网AI领域干货最多的博主之一,❤️不负光阴不负卿❤️​​❤️深度学习模型训练基础环境搭建相关......
  • python 实现远程监控服务器内存,磁盘,cpu各项指标
    点击查看代码#!/usr/local/bin/python3#-*-coding:utf-8-*-importrequestsimportsubprocess,jsonimportparamikoimportsocketNORMAL=0TIMEOUT=2#远程监控......
  • 如何查看CPU和内存使用率
    1、远程登录后,在远程桌面的下边缘有一条横栏叫[任务栏],在[任务栏]空白的地方点击[右键]弹出[右键菜单],选择[任务管理器]或[启动任务管理器]。2、在弹出的[任务管理器]窗口,......
  • 安装华为软件昇腾mindspore-gpu-1.9.0失败记录
    官网安装地址:https://www.mindspore.cn/install  PS:不得不说华为的软件是愈发的不好用了,这个mindspore老版本去年我是使用过的,安装也是比较方便的,搞不清这优化来优......
  • gpu 打满bot 程序
    importtorchimporttimeimportosimportargparseimportshutilimportsysdefparse_args():parser=argparse.ArgumentParser(description='Matrixmulti......
  • cpu放弃线程的时机
    ......
  • 【性能指标分析--CPU篇】
    一、CPU简介CPU又称为中央处理器,是一块超大规模的集成电路,是一台计算机的运算核(Core)和控制核心(ControlUnit)。它的功能主要是解释计算机指令以及处理计算机软件中的数据。......
  • Mali-G57 GPU 性能有多强?
       深圳市新移科技有限公司推出研发科人员基于联发科最新5G手机芯片自主研发且支持AI的处理器 Mali-G57GPU,带有高中低配件引脚P2P兼容,源码兼容。搭载天玑700平台处......
  • (转)linux系统CPU核隔离isolcpu参数设置
    摘自:linux系统CPU隔离isolcpu参数设置_放学有种别跑、的博客-CSDN博客_cpu隔离首先需要说明的是,隔离cpu对用户空间的进程有效,但是对内核的进程无效,所以被隔离的cpu并不是......
  • 云计算-CPU 并行编程-科研路-电动汽车分析
    云计算-CPU并行编程-科研路-电动汽车分析参考文献链接https://mp.weixin.qq.com/s/TSsmcW2i8so_dZ86TRKn0Ahttps://mp.weixin.qq.com/s/19vs_187sVEpW7c4L2aT5whttps:......