CUDA编程一天入门

news2024/11/16 21:32:30

目录

0 环境准备

1  套路

2 并行执行内核设置

3  示例代码simpleTexture3D

4  参考链接


 

0 环境准备

1  套路

CUDA 编程模型是一个异构模型,其中同时使用 CPU 和 GPU。在 CUDA 中,主机是指 CPU 及其内存,而设备是指 GPU 及其内存。在主机上运行的代码可以管理主机和设备上的内存,还可以启动内核,内核是在设备上执行的功能。这些内核由许多 GPU 线程并行执行。

鉴于 CUDA 编程模型的异构性质,CUDA C 程序的典型操作顺序是:

  1. 声明并分配主机和设备内存。
  2. 初始化主机数据。
  3. 将数据从主机传输到设备。
  4. 执行一个或多个内核。
  5. 将结果从设备传输到主机。

2 并行执行内核设置

三重 V 形之间的信息是执行配置,它指示并行执行内核的设备线程数。在 CUDA 中,软件中有一个线程层次结构,它模仿线程处理器在 GPU 上的分组方式。在 CUDA 编程模型中,我们谈到启动带有线程块网格的内核。执行配置中的第一个参数指定网格中的线程块数,第二个参数指定线程块中的线程数。

int blockSize = 256;
int numBlocks = (N + blockSize - 1) / blockSize;
add<<<numBlocks, blockSize>>>(N, x, y);

3  示例代码simpleTexture3D

/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of NVIDIA CORPORATION nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
  3D texture sample

  This sample loads a 3D volume from disk and displays slices through it
  using 3D texture lookups.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <helper_gl.h>

#if defined(__APPLE__) || defined(MACOSX)
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#include <GLUT/glut.h>
#ifndef glutCloseFunc
#define glutCloseFunc glutWMCloseFunc
#endif
#else
#include <GL/freeglut.h>
#endif

// includes, cuda
#include <vector_types.h>
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>

// CUDA utilities and system includes
#include <helper_cuda.h>
#include <helper_functions.h>
#include <vector_types.h>

typedef unsigned int uint;
typedef unsigned char uchar;

#define MAX_EPSILON_ERROR 5.0f
#define THRESHOLD 0.15f

const char *sSDKsample = "simpleTexture3D";

const char *volumeFilename = "Bucky.raw";
const cudaExtent volumeSize = make_cudaExtent(32, 32, 32);

const uint width = 512, height = 512;
const dim3 blockSize(16, 16, 1);
const dim3 gridSize(width / blockSize.x, height / blockSize.y);

float w = 0.5;  // texture coordinate in z

GLuint pbo;  // OpenGL pixel buffer object
struct cudaGraphicsResource
    *cuda_pbo_resource;  // CUDA Graphics Resource (to transfer PBO)

bool linearFiltering = true;
bool animate = true;

StopWatchInterface *timer = NULL;

uint *d_output = NULL;

// Auto-Verification Code
const int frameCheckNumber = 4;
int fpsCount = 0;  // FPS count for averaging
int fpsLimit = 1;  // FPS limit for sampling
int g_Index = 0;
unsigned int frameCount = 0;
unsigned int g_TotalErrors = 0;
volatile int g_GraphicsMapFlag = 0;

int *pArgc = NULL;
char **pArgv = NULL;

#ifndef MAX
#define MAX(a, b) ((a > b) ? a : b)
#endif

extern "C" void cleanup();
extern "C" void setTextureFilterMode(bool bLinearFilter);
extern "C" void initCuda(const uchar *h_volume, cudaExtent volumeSize);
extern "C" void render_kernel(dim3 gridSize, dim3 blockSize, uint *d_output,
                              uint imageW, uint imageH, float w);
extern void cleanupCuda();

void loadVolumeData(char *exec_path);

void computeFPS() {
  frameCount++;
  fpsCount++;

  if (fpsCount == fpsLimit) {
    char fps[256];
    float ifps = 1.f / (sdkGetAverageTimerValue(&timer) / 1000.f);
    sprintf(fps, "%s: %3.1f fps", sSDKsample, ifps);

    glutSetWindowTitle(fps);
    fpsCount = 0;

    fpsLimit = ftoi(MAX(1.0f, ifps));
    sdkResetTimer(&timer);
  }
}

// render image using CUDA
void render() {
  // map PBO to get CUDA device pointer
  g_GraphicsMapFlag++;
  checkCudaErrors(cudaGraphicsMapResources(1, &cuda_pbo_resource, 0));
  size_t num_bytes;
  checkCudaErrors(cudaGraphicsResourceGetMappedPointer(
      (void **)&d_output, &num_bytes, cuda_pbo_resource));
  // printf("CUDA mapped PBO: May access %ld bytes\n", num_bytes);

  // call CUDA kernel, writing results to PBO
  render_kernel(gridSize, blockSize, d_output, width, height, w);

  getLastCudaError("render_kernel failed");

  if (g_GraphicsMapFlag) {
    checkCudaErrors(cudaGraphicsUnmapResources(1, &cuda_pbo_resource, 0));
    g_GraphicsMapFlag--;
  }
}

// display results using OpenGL (called by GLUT)
void display() {
  sdkStartTimer(&timer);

  render();

  // display results
  glClear(GL_COLOR_BUFFER_BIT);

  // draw image from PBO
  glDisable(GL_DEPTH_TEST);
  glRasterPos2i(0, 0);
  glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
  glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

  glutSwapBuffers();
  glutReportErrors();

  sdkStopTimer(&timer);
  computeFPS();
}

void idle() {
  if (animate) {
    w += 0.01f;
    glutPostRedisplay();
  }
}

void keyboard(unsigned char key, int x, int y) {
  switch (key) {
    case 27:
#if defined(__APPLE__) || defined(MACOSX)
      exit(EXIT_SUCCESS);
      glutDestroyWindow(glutGetWindow());
      return;
#else
      glutDestroyWindow(glutGetWindow());
      return;
#endif

    case '=':
    case '+':
      w += 0.01f;
      break;

    case '-':
      w -= 0.01f;
      break;

    case 'f':
      linearFiltering = !linearFiltering;
      setTextureFilterMode(linearFiltering);
      break;

    case ' ':
      animate = !animate;
      break;

    default:
      break;
  }

  glutPostRedisplay();
}

void reshape(int x, int y) {
  glViewport(0, 0, x, y);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
}

void cleanup() {
  sdkDeleteTimer(&timer);

  // add extra check to unmap the resource before unregistering it
  if (g_GraphicsMapFlag) {
    checkCudaErrors(cudaGraphicsUnmapResources(1, &cuda_pbo_resource, 0));
    g_GraphicsMapFlag--;
  }

  // unregister this buffer object from CUDA C
  checkCudaErrors(cudaGraphicsUnregisterResource(cuda_pbo_resource));
  glDeleteBuffers(1, &pbo);
  cleanupCuda();
}

void initGLBuffers() {
  // create pixel buffer object
  glGenBuffers(1, &pbo);
  glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
  glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * sizeof(GLubyte) * 4,
               0, GL_STREAM_DRAW_ARB);
  glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);

  // register this buffer object with CUDA
  checkCudaErrors(cudaGraphicsGLRegisterBuffer(
      &cuda_pbo_resource, pbo, cudaGraphicsMapFlagsWriteDiscard));
}

// Load raw data from disk
uchar *loadRawFile(const char *filename, size_t size) {
  FILE *fp = fopen(filename, "rb");

  if (!fp) {
    fprintf(stderr, "Error opening file '%s'\n", filename);
    return 0;
  }

  uchar *data = (uchar *)malloc(size);
  size_t read = fread(data, 1, size, fp);
  fclose(fp);

  printf("Read '%s', %zu bytes\n", filename, read);

  return data;
}

void initGL(int *argc, char **argv) {
  // initialize GLUT callback functions
  glutInit(argc, argv);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  glutInitWindowSize(width, height);
  glutCreateWindow("CUDA 3D texture");
  glutDisplayFunc(display);
  glutKeyboardFunc(keyboard);
  glutReshapeFunc(reshape);
  glutIdleFunc(idle);

  if (!isGLVersionSupported(2, 0) ||
      !areGLExtensionsSupported("GL_ARB_pixel_buffer_object")) {
    fprintf(stderr, "Required OpenGL extensions are missing.");
    exit(EXIT_FAILURE);
  }
}

void runAutoTest(const char *ref_file, char *exec_path) {
  checkCudaErrors(
      cudaMalloc((void **)&d_output, width * height * sizeof(GLubyte) * 4));

  // render the volumeData
  render_kernel(gridSize, blockSize, d_output, width, height, w);

  checkCudaErrors(cudaDeviceSynchronize());
  getLastCudaError("render_kernel failed");

  void *h_output = malloc(width * height * sizeof(GLubyte) * 4);
  checkCudaErrors(cudaMemcpy(h_output, d_output,
                             width * height * sizeof(GLubyte) * 4,
                             cudaMemcpyDeviceToHost));
  sdkDumpBin(h_output, width * height * sizeof(GLubyte) * 4,
             "simpleTexture3D.bin");

  bool bTestResult = sdkCompareBin2BinFloat(
      "simpleTexture3D.bin", sdkFindFilePath(ref_file, exec_path),
      width * height, MAX_EPSILON_ERROR, THRESHOLD, exec_path);

  checkCudaErrors(cudaFree(d_output));
  free(h_output);

  sdkStopTimer(&timer);
  sdkDeleteTimer(&timer);

  exit(bTestResult ? EXIT_SUCCESS : EXIT_FAILURE);
}

void loadVolumeData(char *exec_path) {
  // load volume data
  const char *path = sdkFindFilePath(volumeFilename, exec_path);

  if (path == NULL) {
    fprintf(stderr, "Error unable to find 3D Volume file: '%s'\n",
            volumeFilename);
    exit(EXIT_FAILURE);
  }

  size_t size = volumeSize.width * volumeSize.height * volumeSize.depth;
  uchar *h_volume = loadRawFile(path, size);

  initCuda(h_volume, volumeSize);
  sdkCreateTimer(&timer);

  free(h_volume);
}


// Program main

int main(int argc, char **argv) {
  pArgc = &argc;
  pArgv = argv;

  char *ref_file = NULL;

#if defined(__linux__)
  setenv("DISPLAY", ":0", 0);
#endif

  printf("%s Starting...\n\n", sSDKsample);

  if (checkCmdLineFlag(argc, (const char **)argv, "file")) {
    fpsLimit = frameCheckNumber;
    getCmdLineArgumentString(argc, (const char **)argv, "file", &ref_file);
  }

  // use command-line specified CUDA device, otherwise use device with highest
  // Gflops/s
  findCudaDevice(argc, (const char **)argv);

  if (ref_file) {
    loadVolumeData(argv[0]);
    runAutoTest(ref_file, argv[0]);
  } else {
    initGL(&argc, argv);

    // OpenGL buffers
    initGLBuffers();

    loadVolumeData(argv[0]);
  }

  printf(
      "Press space to toggle animation\n"
      "Press '+' and '-' to change displayed slice\n");

#if defined(__APPLE__) || defined(MACOSX)
  atexit(cleanup);
#else
  glutCloseFunc(cleanup);
#endif

  glutMainLoop();

  exit(EXIT_SUCCESS);
}
/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of NVIDIA CORPORATION nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _SIMPLETEXTURE3D_KERNEL_CU_
#define _SIMPLETEXTURE3D_KERNEL_CU_

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <helper_cuda.h>
#include <helper_math.h>

typedef unsigned int uint;
typedef unsigned char uchar;

cudaArray *d_volumeArray = 0;
cudaTextureObject_t tex;  // 3D texture

__global__ void d_render(uint *d_output, uint imageW, uint imageH, float w,
                         cudaTextureObject_t texObj) {
  uint x = __umul24(blockIdx.x, blockDim.x) + threadIdx.x;
  uint y = __umul24(blockIdx.y, blockDim.y) + threadIdx.y;

  float u = x / (float)imageW;
  float v = y / (float)imageH;
  // read from 3D texture
  float voxel = tex3D<float>(texObj, u, v, w);

  if ((x < imageW) && (y < imageH)) {
    // write output color
    uint i = __umul24(y, imageW) + x;
    d_output[i] = voxel * 255;
  }
}

extern "C" void setTextureFilterMode(bool bLinearFilter) {
  if (tex) {
    checkCudaErrors(cudaDestroyTextureObject(tex));
  }
  cudaResourceDesc texRes;
  memset(&texRes, 0, sizeof(cudaResourceDesc));

  texRes.resType = cudaResourceTypeArray;
  texRes.res.array.array = d_volumeArray;

  cudaTextureDesc texDescr;
  memset(&texDescr, 0, sizeof(cudaTextureDesc));

  texDescr.normalizedCoords = true;
  texDescr.filterMode =
      bLinearFilter ? cudaFilterModeLinear : cudaFilterModePoint;
  ;
  texDescr.addressMode[0] = cudaAddressModeWrap;
  texDescr.addressMode[1] = cudaAddressModeWrap;
  texDescr.addressMode[2] = cudaAddressModeWrap;
  texDescr.readMode = cudaReadModeNormalizedFloat;

  checkCudaErrors(cudaCreateTextureObject(&tex, &texRes, &texDescr, NULL));
}

extern "C" void initCuda(const uchar *h_volume, cudaExtent volumeSize) {
  // create 3D array
  cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<uchar>();
  checkCudaErrors(cudaMalloc3DArray(&d_volumeArray, &channelDesc, volumeSize));

  // copy data to 3D array
  cudaMemcpy3DParms copyParams = {0};
  copyParams.srcPtr =
      make_cudaPitchedPtr((void *)h_volume, volumeSize.width * sizeof(uchar),
                          volumeSize.width, volumeSize.height);
  copyParams.dstArray = d_volumeArray;
  copyParams.extent = volumeSize;
  copyParams.kind = cudaMemcpyHostToDevice;
  checkCudaErrors(cudaMemcpy3D(&copyParams));

  cudaResourceDesc texRes;
  memset(&texRes, 0, sizeof(cudaResourceDesc));

  texRes.resType = cudaResourceTypeArray;
  texRes.res.array.array = d_volumeArray;

  cudaTextureDesc texDescr;
  memset(&texDescr, 0, sizeof(cudaTextureDesc));

  // access with normalized texture coordinates
  texDescr.normalizedCoords = true;
  // linear interpolation
  texDescr.filterMode = cudaFilterModeLinear;
  // wrap texture coordinates
  texDescr.addressMode[0] = cudaAddressModeWrap;
  texDescr.addressMode[1] = cudaAddressModeWrap;
  texDescr.addressMode[2] = cudaAddressModeWrap;
  texDescr.readMode = cudaReadModeNormalizedFloat;

  checkCudaErrors(cudaCreateTextureObject(&tex, &texRes, &texDescr, NULL));
}

extern "C" void render_kernel(dim3 gridSize, dim3 blockSize, uint *d_output,
                              uint imageW, uint imageH, float w) {
  d_render<<<gridSize, blockSize>>>(d_output, imageW, imageH, w, tex);
}

void cleanupCuda() {
  if (tex) {
    checkCudaErrors(cudaDestroyTextureObject(tex));
  }
  if (d_volumeArray) {
    checkCudaErrors(cudaFreeArray(d_volumeArray));
  }
}

#endif  // #ifndef _SIMPLETEXTURE3D_KERNEL_CU_

4  参考链接

GitHub - NVIDIA/cuda-samples: Samples for CUDA Developers which demonstrates features in CUDA Toolkit

CUDA routines are functions that can be executed on the GPU using many threads in parallel1. There are many CUDA code samples included as part of the CUDA Toolkit to help you get started on writing CUDA C/C++ applications2. You can also find some easy introductions to CUDA C and C++ on the NVIDIA Technical Blog31.

GitHub - LitLeo/OpenCUDA  

CUDA开发环境搭建 - 知乎 (zhihu.com)  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/438655.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Prophet学习(三)饱和的预测与饱和最低

目录 饱和的预测&#xff08;Forecasting Growth&#xff09; 饱和最低&#xff08;Saturating Minimum&#xff09; 饱和的预测&#xff08;Forecasting Growth&#xff09; 默认情况下&#xff0c;Prophet使用线性模型进行预测。在预测增长时&#xff0c;通常有一个最大可达…

Ubuntu22.04lts NVIDIA驱动安装

1. NVIDIA驱动安装 1.1 手动安装 驱动下载地址&#xff1a;NVIDIA Driver Downloads 注意要在文本模式安装&#xff0c;进入文本模式的方法&#xff1a;sudo init 3。 返回图形化界面的方法sudo init 5 安装时报错&#xff1a; 安装NVIDIA驱动&#xff08;手动安装NVIDIA-L…

两种方式,轻松实现ChatGPT联网

两种方式效果&#xff1a; 方式一&#xff1a;浏览器搜索内嵌插件 方式二&#xff1a;官方聊天页内嵌插件 首先&#xff0c;要有一个谷歌浏览器&#xff0c;然后再安装一个叫ChatGPT for Google&#xff0c;直接在谷歌里搜一下就能找&#xff0c;也可以Chrome应用商店里搜索&a…

SAP批次主数据增强屏幕增强<转载>

原文链接&#xff1a;https://blog.csdn.net/hustliangchen/article/details/111163361 msc1n/msc2n/msc3n 批次增强 这几个事务码的主程序为SAPLCHRG&#xff0c;在如下图界面上有两块地方是可以做增强所预留的子屏幕&#xff0c;其中2是一个tab页签的子屏幕。注意版本较老的…

AI企划-《大明镇抚司到此一游》商业计划书

结合中国文化和当地资源打造的独特旅游产品 一、项目概述 本项目旨在利用中国文化特色&#xff0c;结合新西兰当地资源和市场需求&#xff0c;打造一款独特的旅游产品——“大明镇抚司到此一游”网红打卡点。该打卡点以大明镇抚司为主题&#xff0c;以大明小龙虾美食为特色&am…

千亿市场!低代码平台极大提升企业应用开发效率,颠覆传统模式!

背景 低代码平台的5个核心亮点&#xff1a; 可视化的表单设计&#xff1b; 2.可视化的审批流&#xff0c;逻辑流设计&#xff1b; 3.可视化的BI图标设计&#xff1b; 4.可视化的以应用为中心的开放和集成接口设计&#xff1b; 5.以应用为中心&#xff0c;依托于云原生技术的快…

线性表,栈和队列

什么是线性表&#xff1f; 线性表是由n个相同类型的数据元素组成的有限序列&#xff0c;它是最基本的一种线性结构。顾名思义&#xff0c;线性表就像是一条线&#xff0c;不会分叉。线性表有唯一的开始和结束&#xff0c;除了第一个元素外&#xff0c;每个元素都有唯一的直接前…

docker容器:docker资源管理

目录 一、docker资源控制 1、资源控制工具 2、设置CPU使用率上限 3、CPU压力测试 4、Cgroups限制cpu使用率 5、查看容器运行状态 6、 配置容器指定CPU 7、限制容器内存使用 8、对磁盘IO配额控制&#xff08;blkio&#xff09;的限制 二、docker数据管理 1、数据管理…

量子退火算法入门(7):如何QUBO中的三次多项式怎么转换?

文章目录 前言一、三次多项式的例题二、Python实现1.引入库 总结 前言 本文还是大部分截图来自于&#xff1a;《最適化問題とWildqatを用いた量子アニーリング計算入門》 https://booth.pm/ja/items/1415833 终于有人问到怎么将QUBO中的三次多项式转换为二次多项式了。直接以…

购物车--购物车模块完善

很明显&#xff0c;之前的购物车模块功能的实现不够完善&#xff0c;缺少一个删除购物车中产品的操作&#xff0c;针对此我们加一个删除功能。 1、写负责删除的servelt类 2、然后我们给购物车页面的jsp添加超链接传递目标id 搞定。

王道计组(23版)1_计算机系统概述

1.计算机发展历程 硬件的发展&#xff1a; 电子管、晶体管、中小规模集成电路、超大规模集成电路 摩尔定律&#xff1a; 价格不变时&#xff0c;每18个月&#xff0c;集成电路可容纳的晶体管数量和性能增加一倍 微型计算机的发展以微处理器技术为标志 计算机体系结构&#xf…

u盘里的文件被自动删除了怎么办?五种数据恢复方案

u盘是我们日常生活中常常用到的一种便携式存储设备&#xff0c;可以帮助我们存储和携带大量的文件信息。但是&#xff0c;使用过程中难免会遇到一些问题&#xff0c;例如u盘会自己删除文件的情况&#xff0c;如果你遇到了这种情况&#xff0c;该怎样找回u盘自己删除的文件呢&am…

程序猿眼中的协议:TCP / IP 五层网络模型

哈喽&#xff0c;大家好~我是你们的老朋友&#xff1a; 保护小周ღ&#xff0c;本期为大家带来的是 网络基础原理中的 TCP / IP 五层网络模型&#xff0c;主要从协议的概念&#xff0c;网络模型&#xff0c;数据分层传输的流程&#xff0c;几个方面讲解&#xff0c;看完之后可以…

jdk-FuteureForkJoin框架源码学习

背景 日常的计算任务大部分都是串行来执行&#xff0c;但是如果一个复杂的任务需要进行拆分为多个小任务&#xff0c;那么以往是自行写一个递归或者循环计算等算法来实现&#xff0c;随着这类需求的提升&#xff0c;java7中引入了ForkJoin框架来支持这类计算&#xff0c;可以比…

计算机组成原理——第六章总线

误逐世间乐&#xff0c;颇穷理乱情 文章目录 前言6.1.1 总线概述6.1.2 总线的性能指标6.2 总线仲裁(408不考)6.3 总线操作和定时 前言 本章在概述部分我们会首先介绍一下总线的基本概念&#xff0c;介绍一下总线的分类以及经典结构&#xff0c;介绍一些性能指标来评价总线的性…

部分面试题记录

Spring相关&#xff1a; 1. spring框架中的单例bean是线程安全的嘛&#xff1f; 1.1 bean单例多例配置&#xff1a; bean可以手动设置单例或者多例&#xff1a; Service Scope("singleton") public class UserServicelmpl implements UserService { }singleton:b…

QT学习笔记4

一.UI的使用 ui代码输入&#xff1a; ui->setupUi(this);ui->statusbar->showMessage("作者",3000); 在ui类中调用 二.对话框QDialong 模态对话框&#xff1a;就是会阻塞同一应用程序中其它窗口的输入 非模态对话框&#xff1a;不会堵塞同一应用程序中其…

Python反序列化漏洞及魔术方法详细全解(链构造、自动审计工具bandit)

目录 一、Python序列化反序列化相关函数 二、Python魔术方法 三、魔术方法实例详解 <__reduce__> <__setstate__> <__getstate__> 四、反序列化安全漏洞的产生 五、真题实例 六、CTF-CISCN华北-JWT&反序列化 七、代码审计自动化工具——bandit …

理解unsafe-assume-no-moving-gc包

1. 背景 在之前的《Go与神经网络&#xff1a;张量计算》[1]一文中&#xff0c;不知道大家是否发现了&#xff0c;所有例子代码执行时&#xff0c;前面都加了一个环境变量ASSUME_NO_MOVING_GC_UNSAFE_RISK_IT_WITH&#xff0c;就像下面这样&#xff1a; $ASSUME_NO_MOVING_GC_UN…

单片机--第六章中断系统例子学习

单片机--第六章中断系统例子学习 例6-2 P0口连上8个LED&#xff0c; 13引脚&#xff08;INT0&#xff09;上接了一个按钮&#xff0c;要求每次按钮均能改变LED的亮灭 代码&#xff1a; #include<reg51.h> #define LED P0sbit KEYP3^3; bit flag0;//延时函数 void dela…