每日总结(2022/05/17-)


实现2个矩阵(Width=2048, Height=1024)的相加,输入的矩阵A,B按照以下要求初始化,矩阵A的初始值全为本人学号的最后1位数字,矩阵B的初始值全为本人学号的倒数第2位数字。同时用CPU代码实现,比较两个代码的运行时间。

  • 用二维线程结构来计算矩阵加法,每一个线程对应一个矩阵元素

线程配置

在这里插入图片描述
从上图得出我的计算机在每个Block有128,256,512个线程时,资源利用率最大。

int nx = 2048;
int ny = 1024;
dim3 threadsPerBlock(16, 16);
dim3 blocksPerGrid((nx - 1) / 16+1, (ny - 1) /16+1); //dim3 blocksPerGrid(128,64)

实验设备

设备名称与型号,显存大小,含有的SM数量,CUDA CORE数量,计算能力。
可以使用以下代码查看需要的信息。

void GetDeviceInfo()
{
    cudaDeviceProp deviceProp;
    cudaGetDeviceProperties(&deviceProp, 0);
    printf("Device 0 information:\n");
    printf("设备名称与型号: %s\n", deviceProp.name);
    printf("显存大小: %d MB\n", (int)(deviceProp.totalGlobalMem / 1024 / 1024));
    printf("含有的SM数量: %d\n", deviceProp.multiProcessorCount);
    printf("CUDA CORE数量: %d\n", deviceProp.multiProcessorCount * 128);
    printf("计算能力: %d.%d\n", deviceProp.major, deviceProp.minor);
}

在这里插入图片描述
也可用调用deviceQuery.exe查看详情。
在这里插入图片描述

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <chrono>
#include <cuda_runtime.h>
#include <stdio.h>
#include <iostream>

using namespace std;


//检查返回是否正确
void CHECK(cudaError error)
{

  if(error!=cudaSuccess)
  {
      printf("ERROR: %s:%d,",__FILE__,__LINE__);
      printf("code:%d,reason:%s\n",error,cudaGetErrorString(error));
      exit(1);
  }
}

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 initialMatrix(float* ip, int s, const int t)
{
	if (t == 0)
	{
		for (int i = 0; i < s; i++)
		{
			ip[i] = 0.0;
		}
	}
	else if (t == 1)
	{
		for (int i = 0; i < s; i++)
		{
			ip[i] = 6.0;
		}
	}
	else
	{
		for (int i = 0; i < s; i++)
		{
			ip[i] = 0.0;
		}
	}
}

void checkResult(float* host, float* device, const int N)
{
	double epsilon = 1.0E-8;
	for (int i = 0; i < N; i++)
	{
		if (abs(host[i] - device[i]) > epsilon)
		{
			printf("Not match!\n");
			printf("%f(host[%d])!= %f(device[%d])\n", host[i], i, device[i], i);
			return;
		}
	}
	printf("Match\n");
}


//CPU运行同样的矩阵加法,对比host和device的运行速度
void sumMatrix2DonCPU(float* MatA, float* MatB, float* MatC, int nx, int ny)
{
	float* a = MatA;
	float* b = MatB;
	float* c = MatC;
	for (int j = 0; j < ny; j++)
	{
		for (int i = 0; i < nx; i++)
		{
			c[i] = a[i] + b[i];
		}
		c += nx;
		b += nx;
		a += nx;
	}
}




__global__ void sumMatrix(float* MatA, float* MatB, float* MatC, int nx, int ny)
{
	int ix = threadIdx.x + blockDim.x * blockIdx.x;
	int iy = threadIdx.y + blockDim.y * blockIdx.y;
	int idx = ix + iy * nx;
	if (ix < nx && iy < ny)
	{
		MatC[idx] = MatA[idx] + MatB[idx];
	}
}
int main(int argc, char** argv)
{


	//设备初始化
	printf("strating...\n");
	initDevice(0);

	//输入二维矩阵,2048*1024,单精度浮点型。
	int nx = 2048;
	int ny = 1024;
	int size = nx * ny * sizeof(float);

	//Malloc,分配host内存
	float* A_host = (float*)malloc(size);
	float* B_host = (float*)malloc(size);
	float* C_host = (float*)malloc(size);
	float* C_from_gpu = (float*)malloc(size);
	initialMatrix(A_host, nx * ny, 0);
	initialMatrix(B_host, nx * ny, 1);

	//cudaMalloc,分配device内存
	float* A_dev = NULL;
	float* B_dev = NULL;
	float* C_dev = NULL;
	CHECK(cudaMalloc((void**)&A_dev, size));
	CHECK(cudaMalloc((void**)&B_dev, size));
	CHECK(cudaMalloc((void**)&C_dev, size));

	//输入数据从host拷贝到device
	CHECK(cudaMemcpy(A_dev, A_host, size, cudaMemcpyHostToDevice));
	CHECK(cudaMemcpy(B_dev, B_host, size, cudaMemcpyHostToDevice));


	dim3 threadsPerBlock(16, 16);
	cout << "threadsPerBlock.x = " << threadsPerBlock.x << endl;
	cout << "threadsPerBlock.y = " << threadsPerBlock.y << endl;

	dim3 blocksPerGrid((nx - 1) / 16 + 1, (ny - 1) / 16 + 1);
	cout << "blocksPerGrid.x = " << blocksPerGrid.x << "   blocksPerGrid.y=" << blocksPerGrid.y << endl;

	//测试GPU执行时间
	//double gpuStart = cpuSecond();
	//将核函数放在线程网格中执行
	auto beforeTime = std::chrono::steady_clock::now();
	sumMatrix << <blocksPerGrid, threadsPerBlock >> > (A_dev, B_dev, C_dev, nx, ny);
	auto afterTime = std::chrono::steady_clock::now();
	double duration_millsecond = std::chrono::duration<double, std::milli>(afterTime - beforeTime).count();
	CHECK(cudaDeviceSynchronize());

	printf("GPU Execution Time: %f ms\n", duration_millsecond);

	//在CPU上完成相同的任务
	cudaMemcpy(C_from_gpu, C_dev, size, cudaMemcpyDeviceToHost);
	beforeTime = std::chrono::steady_clock::now();
	sumMatrix2DonCPU(A_host, B_host, C_host, nx, ny);
	afterTime = std::chrono::steady_clock::now();
	duration_millsecond = std::chrono::duration<double, std::milli>(afterTime - beforeTime).count();

	printf("CPU Execution Time: %f ms\n", duration_millsecond);

	//检查GPU与CPU计算结果是否相同
	CHECK(cudaMemcpy(C_from_gpu, C_dev, size, cudaMemcpyDeviceToHost));
	checkResult(C_host, C_from_gpu, nx * ny);

	//释放内存
	cudaFree(A_dev);
	cudaFree(B_dev);
	cudaFree(C_dev);
	free(A_host);
	free(B_host);
	free(C_host);
	free(C_from_gpu);
	cudaDeviceReset();


	return 0;
}

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个简单的盈利模型可以使用简单移动平均线(SMA)和价格的相对强弱指标(RSI)。在这里,我们使用5天的SMA和14天的RSI。 步骤1:计算5天的SMA 将前5天每日的收盘价加起来,除以5得到5天SMA。对于第6天以后的每一天,使用前5天的收盘价数据,将最后一个数据删掉,加上当天的收盘价,再除以5得到新的5天SMA。例如,第6天的SMA是(18.39 + 18.22 + 18.62 + 18.36 + 18.45)/ 5 = 18.48,第7天的SMA是(18.22 + 18.62 + 18.36 + 18.45 + 17.89)/ 5 = 18.11。 步骤2:计算14天的RSI 日价格变化的平均值为14天,其中日涨幅不为零的值与日跌幅不为零的值分别计算得到。每天的变化值为当天的收盘价减去前一天的收盘价的绝对值,如果涨了则记为正值,如果跌了则记为负值。然后计算14天涨幅的平均值和14天跌幅的平均值分别为U和D。计算RSI的公式为:RSI = 100 - (100 / (1 + U / D))。例如,第14天的U为(17.43 - 17.89)= 0.46,D为0,因为当天的收盘价较前一天下跌了。前14天的U和D可以使用同样的方法来计算。 步骤3:判断买入或卖出信号 当价格在5天SMA上方,并且RSI超过70时,表明股票处于超买状态,这时候可以考虑卖出;当价格在5天SMA下方,并且RSI低于30时,表明股票处于超卖状态,这时候可以考虑买入。 这是一个简单的数学模型,实际操作是复杂的,需要注意多个因素的综合考虑,并且需要进行风险管理。此处提供的仅为理论模型,仅供参考。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值