CUDA L2Cache Profing

news/2024/9/19 0:47:16/ 标签: CUDA, GPU, GPGPU, 性能优化, 性能分析

CUDA L2Cache Profing

  • 一.小结
  • 二.测试L2 Cache的驱逐策略
  • 三.测试Kernel执行完成后,l2Cache是否会被清

一.小结

  • 当所有的warp都访问 2(warpcount)*32(threads)*4(bytes)的DRAM区间时,因DRAM BANK冲突,导致耗时太长
  • 开启l2 cache后,性能大幅提升
  • 推测kernel执行完之后或运行之前,L2Cache会被invalidate,导致新的Kernel复用同一块内存时,LD指令的耗时没有明显降低
    • Profing发现l2 cache hit也没有变化
    • 也有可能因L2容量太小,导致差异不明显

二.测试L2 Cache的驱逐策略

tee l2cache_test.cu<<-'EOF'
#include <iostream>
#include <cuda_runtime.h>
#include <iostream>
#include <vector>
#include <stdio.h>
#include <assert.h>
#include <cstdio>
#include <cuda.h>#define CHECK_CUDA(call)                                           \do {                                                           \cudaError_t err = call;                                    \if (err != cudaSuccess) {                                  \std::cerr << "CUDA error at " << __FILE__ << ":" << __LINE__; \std::cerr << " code=" << err << " (" << cudaGetErrorString(err) << ")" << std::endl; \exit(EXIT_FAILURE);                                    \}                                                          \} while (0)__global__ void kernel(float *addr,int warp_count)
{unsigned int tid  = threadIdx.x + blockIdx.x * blockDim.x;    unsigned int warp_index=tid/32;unsigned int warp_offset=tid%32;warp_index=warp_index%100;//所有warp复用100(warp)*4(secotrs)*32(字节)=12800字节的数据//按warp访问,可以保证每次获取一个cacheline的数据unsigned int offset=warp_index*32+warp_offset;float value;//设置二种不同的驱逐方式if(warp_index<50){asm("ld.global.L1::evict_first.f32  %0, [%1];" : "=f"(value) : "l"(&addr[offset]));}else{asm("ld.global.L1::evict_last.f32  %0, [%1];" : "=f"(value) : "l"(&addr[offset]));}//asm("ld.global.cg.f32 %0, [%1];" : "=f"(value) : "l"(&addr[offset]));//asm("ld.global.L1::evict_normal.f32  %0, [%1];" : "=f"(value) : "l"(&addr[offset]));value+=tid;//addr[offset]=value;asm("st.global.wt.f32 [%0],%1;" :: "l"(&addr[offset]),"f"(value));
}__global__ void kernel_big(float *addr,int warp_count)
{unsigned int tid  = threadIdx.x + blockIdx.x * blockDim.x;    unsigned int warp_index=tid/32;unsigned int warp_offset=tid%32;warp_index=warp_index%30000;unsigned int offset=warp_index*32+warp_offset;float value;//设置二种不同的驱逐方式if(warp_index<15000){asm("ld.global.L1::evict_first.f32  %0, [%1];" : "=f"(value) : "l"(&addr[offset]));}else{asm("ld.global.L1::evict_last.f32  %0, [%1];" : "=f"(value) : "l"(&addr[offset]));}//asm("ld.global.cg.f32 %0, [%1];" : "=f"(value) : "l"(&addr[offset]));//asm("ld.global.L1::evict_normal.f32  %0, [%1];" : "=f"(value) : "l"(&addr[offset]));value+=tid;//addr[offset]=value;asm("st.global.wt.f32 [%0],%1;" :: "l"(&addr[offset]),"f"(value));
}int main(int argc,char *argv[])
{int deviceid=0;cudaSetDevice(deviceid);int block_count=28*10000;int block_size=32*4*8;int thread_size=block_count*block_size;int warp_count=thread_size/32;printf("total secotrs:%d\n",thread_size*4/32);float *addr;CHECK_CUDA(cudaMalloc(&addr, thread_size*4));kernel<<<block_count, block_size>>>(addr,warp_count);kernel<<<block_count, block_size>>>(addr,warp_count);CHECK_CUDA(cudaDeviceSynchronize());kernel_big<<<block_count, block_size>>>(addr,warp_count);CHECK_CUDA(cudaDeviceSynchronize());    return 0;
}
EOF
/usr/local/cuda/bin/nvcc -std=c++17 -arch=sm_86 -lineinfo  -o l2cache_test l2cache_test.cu \-I /usr/local/cuda/include -L /usr/local/cuda/lib64 -lcuda/usr/local/NVIDIA-Nsight-Compute/ncu --metrics \
smsp__sass_inst_executed_op_global_ld.sum,\
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit,\
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.sum,\
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_miss.sum,\
lts__t_sectors_srcunit_tex_op_read_evict_last_lookup_hit.sum,\
lts__t_sectors_srcunit_tex_op_read_evict_last_lookup_miss.sum,\
lts__t_sectors_srcunit_tex_op_read_evict_normal_lookup_hit.sum,\
lts__t_sectors_srcunit_tex_op_read_evict_normal_lookup_miss.sum,\
lts__t_requests_srcunit_tex_op_read.sum,\
l1tex__m_xbar2l1tex_read_sectors_mem_lg_op_ld.sum,\
l1tex__t_sector_pipe_lsu_mem_global_op_ld_hit_rate.pct,\
smsp__sass_l1tex_m_xbar2l1tex_read_sectors_mem_global_op_ldgsts_cache_bypass.sum,\
lts__t_sectors_srcunit_tex_op_read.sum ./l2cache_test

输出

total secotrs:35840000
kernel(float *, int) (280000, 1, 1)x(1024, 1, 1), Context 1, Stream 7, Device 0, CC 8.6
Section: Command line profiler metrics
-------------------------------------------------------------------------------- ----------- ------------
Metric Name                                                                      Metric Unit Metric Value
-------------------------------------------------------------------------------- ----------- ------------
l1tex__m_xbar2l1tex_read_sectors_mem_lg_op_ld.sum                                     sector       11,200 #100(warp)*4(secotrs)*28(sm)=11200
l1tex__t_sector_pipe_lsu_mem_global_op_ld_hit_rate.pct                                     %        99.97 #(35840000-11200)/35840000=0.9996875=99.968%->99.97%
lts__t_requests_srcunit_tex_op_read.sum                                              request        2,800 #*100(warp)*28(sm)=2800
lts__t_sectors_srcunit_tex_op_read.sum                                                sector       11,200
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.sum                         sector        5,400 #11200/2-200=5400
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_miss.sum                        sector          200 #50(warp)*4(secotrs)=200
lts__t_sectors_srcunit_tex_op_read_evict_last_lookup_hit.sum                          sector            0 #TODO
lts__t_sectors_srcunit_tex_op_read_evict_last_lookup_miss.sum                         sector            0
lts__t_sectors_srcunit_tex_op_read_evict_normal_lookup_hit.sum                        sector        5,400 #同上
lts__t_sectors_srcunit_tex_op_read_evict_normal_lookup_miss.sum                       sector          200
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.avg                         sector          300 #sum/avg=5400/300=18(l2 slice个数)
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.max                         sector          864 #
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.min                         sector            0 #说明不均衡
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.sum                         sector        5,400
smsp__sass_inst_executed_op_global_ld.sum                                               inst    8,960,000 #总的warp指令条数=28*10000*4*8=8960000
smsp__sass_l1tex_m_xbar2l1tex_read_sectors_mem_global_op_ldgsts_cache_bypass.sum      sector            0
-------------------------------------------------------------------------------- ----------- ------------kernel(float *, int) (280000, 1, 1)x(1024, 1, 1), Context 1, Stream 7, Device 0, CC 8.6
Section: Command line profiler metrics
-------------------------------------------------------------------------------- ----------- ------------
Metric Name                                                                      Metric Unit Metric Value
-------------------------------------------------------------------------------- ----------- ------------
l1tex__m_xbar2l1tex_read_sectors_mem_lg_op_ld.sum                                     sector       11,200
l1tex__t_sector_pipe_lsu_mem_global_op_ld_hit_rate.pct                                     %        99.97
lts__t_requests_srcunit_tex_op_read.sum                                              request        2,800
lts__t_sectors_srcunit_tex_op_read.sum                                                sector       11,200
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.sum                         sector        5,400
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_miss.sum                        sector          200 #跟上面的Kernel一样,难道kernel执行完成之后,L2Cache被清了?
lts__t_sectors_srcunit_tex_op_read_evict_last_lookup_hit.sum                          sector            0
lts__t_sectors_srcunit_tex_op_read_evict_last_lookup_miss.sum                         sector            0
lts__t_sectors_srcunit_tex_op_read_evict_normal_lookup_hit.sum                        sector        5,400
lts__t_sectors_srcunit_tex_op_read_evict_normal_lookup_miss.sum                       sector          200
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.avg                         sector          300
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.max                         sector          864
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.min                         sector            0
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.sum                         sector        5,400
smsp__sass_inst_executed_op_global_ld.sum                                               inst    8,960,000
smsp__sass_l1tex_m_xbar2l1tex_read_sectors_mem_global_op_ldgsts_cache_bypass.sum      sector            0
-------------------------------------------------------------------------------- ----------- ------------kernel_big(float *, int) (280000, 1, 1)x(1024, 1, 1), Context 1, Stream 7, Device 0, CC 8.6
Section: Command line profiler metrics
-------------------------------------------------------------------------------- ----------- ------------
Metric Name                                                                      Metric Unit Metric Value
-------------------------------------------------------------------------------- ----------- ------------
l1tex__m_xbar2l1tex_read_sectors_mem_lg_op_ld.sum                                     sector   35,473,928
l1tex__t_sector_pipe_lsu_mem_global_op_ld_hit_rate.pct                                     %         1.05
lts__t_requests_srcunit_tex_op_read.sum                                              request    8,868,482
lts__t_sectors_srcunit_tex_op_read.sum                                                sector   35,473,928
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.sum                         sector            0
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_miss.sum                        sector   17,753,904 #超过Cache大小时,cache失效
lts__t_sectors_srcunit_tex_op_read_evict_last_lookup_hit.sum                          sector            0
lts__t_sectors_srcunit_tex_op_read_evict_last_lookup_miss.sum                         sector            0
lts__t_sectors_srcunit_tex_op_read_evict_normal_lookup_hit.sum                        sector            0
lts__t_sectors_srcunit_tex_op_read_evict_normal_lookup_miss.sum                       sector   17,713,084
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.avg                         sector            0
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.max                         sector            0
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.min                         sector            0
lts__t_sectors_srcunit_tex_op_read_evict_first_lookup_hit.sum                         sector            0
smsp__sass_inst_executed_op_global_ld.sum                                               inst    8,960,000
smsp__sass_l1tex_m_xbar2l1tex_read_sectors_mem_global_op_ldgsts_cache_bypass.sum      sector            0
-------------------------------------------------------------------------------- ----------- ------------

三.测试Kernel执行完成后,l2Cache是否会被清

  • 输出
total secotrs:35840000
warpup
kernel_without_l2cache
E2E:20.6264 ms Kernel:20.6138 ms  #当所有的warp都访问 2(warpcount)*32(threads)*4(bytes)的DRAM区间时,因DRAM BANK冲突,导致耗时太长
E2E:20.5642 ms Kernel:20.5536 ms
E2E:20.5506 ms Kernel:20.5413 ms
kernel_l2cache
E2E:3.85756 ms Kernel:3.84717 ms  #当开启l2 cache后,性能大幅提升
E2E:3.85328 ms Kernel:3.84512 ms
E2E:3.85268 ms Kernel:3.84416 ms
kernel_l2cache+Invalidate
E2E:3.85734 ms Kernel:3.84602 ms  #每次执行完Kernel后,Invalidate the data in l2,性能没有差异,推测Kernel执行完之后或之前,内部会刷l2 cache
E2E:3.85134 ms Kernel:3.84512 ms
E2E:3.85482 ms Kernel:3.8441 ms
  • 复现过程
tee l2cache_test.cu<<-'EOF'
#include <iostream>
#include <cuda_runtime.h>
#include <iostream>
#include <vector>
#include <stdio.h>
#include <assert.h>
#include <cstdio>
#include <cuda.h>
#include <iostream>
#include <chrono>
#include <thread>#define CHECK_CUDA(call)                                           \do {                                                           \cudaError_t err = call;                                    \if (err != cudaSuccess) {                                  \std::cerr << "CUDA error at " << __FILE__ << ":" << __LINE__; \std::cerr << " code=" << err << " (" << cudaGetErrorString(err) << ")" << std::endl; \exit(EXIT_FAILURE);                                    \}                                                          \} while (0)__constant__  unsigned int warp_count=2;__global__ void kernel_without_l2cache(volatile float *input,volatile float *output)
{unsigned int tid  = threadIdx.x + blockIdx.x * blockDim.x;    unsigned int warp_index=tid/32;unsigned int warp_offset=tid%32;warp_index=warp_index%warp_count;unsigned int offset=warp_index*32+warp_offset;   float value=0;    asm volatile ("ld.global.cv.f32 %0, [%1];" : "=f"(value) : "l"(&input[offset]));if(tid==0){printf("%f\r",value);}
}__global__ void kernel_l2cache(volatile float *input,volatile float *output)
{unsigned int tid  = threadIdx.x + blockIdx.x * blockDim.x;    unsigned int warp_index=tid/32;unsigned int warp_offset=tid%32;warp_index=warp_index%warp_count;unsigned int offset=warp_index*32+warp_offset;   float value=0;    asm volatile ("ld.global.L1::evict_last.f32 %0, [%1];" : "=f"(value) : "l"(&input[offset]));if(tid==0){printf("%f\r",value);}
}__global__ void invalidate_l2cache(volatile float *input,volatile float *output)
{unsigned int tid  = threadIdx.x + blockIdx.x * blockDim.x;    unsigned int warp_index=tid/32;unsigned int warp_offset=tid%32;warp_index=warp_index%warp_count;if(warp_offset==0){unsigned int offset=warp_index*32+warp_offset;   asm("discard.global.L2 [%0],128;" :: "l"(&input[offset]));//Invalidate the data in L2}
}int main(int argc,char *argv[])
{int deviceid=0;cudaSetDevice(deviceid);int block_count=28*10000;int block_size=32*4*8;int thread_size=block_count*block_size;printf("total secotrs:%d\n",thread_size*4/32);{//warpupprintf("warpup\n");float *addr;CHECK_CUDA(cudaMalloc(&addr, thread_size*4));kernel_l2cache<<<block_count, block_size>>>(addr,addr);kernel_without_l2cache<<<block_count, block_size>>>(addr,addr);cudaDeviceSynchronize();cudaFree(addr);}float *addr;CHECK_CUDA(cudaMalloc(&addr, thread_size*4));cudaStream_t stream;cudaStreamCreate(&stream);cudaEvent_t start_ev, stop_ev;cudaEventCreate(&start_ev);cudaEventCreate(&stop_ev);printf("kernel_without_l2cache\n");for(int i=0;i<3;i++){      auto start = std::chrono::high_resolution_clock::now();cudaEventRecord(start_ev, stream);kernel_without_l2cache<<<block_count, block_size,0,stream>>>(addr,addr);cudaEventRecord(stop_ev, stream);CHECK_CUDA(cudaEventSynchronize(stop_ev));auto end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> diff = end - start;float milliseconds = 0;cudaEventElapsedTime(&milliseconds, start_ev, stop_ev);std::cout << "E2E:" << diff.count()*1000 << " ms" << " Kernel:" << milliseconds << " ms" << std::endl;}printf("kernel_l2cache\n");for(int i=0;i<3;i++){      auto start = std::chrono::high_resolution_clock::now();cudaEventRecord(start_ev, stream);kernel_l2cache<<<block_count, block_size,0,stream>>>(addr,addr);cudaEventRecord(stop_ev, stream);CHECK_CUDA(cudaEventSynchronize(stop_ev));auto end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> diff = end - start;float milliseconds = 0;cudaEventElapsedTime(&milliseconds, start_ev, stop_ev);std::cout << "E2E:" << diff.count()*1000 << " ms" << " Kernel:" << milliseconds << " ms" << std::endl;}   printf("kernel_l2cache+Invalidate\n");    for(int i=0;i<3;i++){invalidate_l2cache<<<block_count, block_size>>>(addr,addr);cudaDeviceSynchronize();auto start = std::chrono::high_resolution_clock::now();cudaEventRecord(start_ev, stream);kernel_l2cache<<<block_count, block_size,0,stream>>>(addr,addr);cudaEventRecord(stop_ev, stream);CHECK_CUDA(cudaEventSynchronize(stop_ev));auto end = std::chrono::high_resolution_clock::now();std::chrono::duration<double> diff = end - start;float milliseconds = 0;cudaEventElapsedTime(&milliseconds, start_ev, stop_ev);std::cout << "E2E:" << diff.count()*1000 << " ms" << " Kernel:" << milliseconds << " ms" << std::endl;}return 0;
}
EOF
/usr/local/cuda/bin/nvcc -std=c++17 -arch=sm_86 \-o l2cache_test l2cache_test.cu \-I /usr/local/cuda/include -L /usr/local/cuda/lib64 -lcuda
./l2cache_test

http://www.ppmy.cn/news/1523792.html

相关文章

Kafka【十二】消费者拉取主题分区的分配策略

【1】消费者组、leader和follower 消费者想要拉取主题分区的数据&#xff0c;首先必须要加入到一个组中。 但是一个组中有多个消费者的话&#xff0c;那么每一个消费者该如何消费呢&#xff0c;是不是像图中一样的消费策略呢&#xff1f;如果是的话&#xff0c;那假设消费者组…

Redis:发布(pub)与订阅(sub)实战

前言 Redis发布订阅&#xff08;Pub/Sub&#xff09;是Redis提供的一种消息传递机制&#xff0c;它使用“发布者-订阅者”&#xff08;publisher-subscriber&#xff09;模式来处理消息传递。在这种模式下&#xff0c;发布者将消息发布到一组订阅者中&#xff0c;而无需关心谁…

用华为智驾,开启MPV的下半场

作者 |老缅 编辑 |德新 8月28日&#xff0c;岚图正式对外公布了全球首款搭载华为乾崑智驾和鸿蒙座舱的MPV——全新岚图梦想家。 新车定位「全景豪华科技旗舰MPV」&#xff0c;全系标配四驱&#xff0c;分为四驱鲲鹏版和四驱乾崑版。 其中岚图逍遥座舱和鲲鹏智驾构成的鲲鹏版…

重命名工具 | Advanced Renamer v4.03 绿色版

Advanced Renamer 是一款专为 Windows 平台设计的强大文件批量重命名工具。它提供了多种重命名方法&#xff0c;包括指定新文件名、改变大小写、移动字符、移除字符串、重编文件名序号、替换字符、添加内容、使用列表或列表文件替换文件名、交换字符位置、去除头部或尾部多余空…

快速理解Redis

Redis 是一种开源的、基于内存的数据结构存储系统&#xff0c;它可以用作数据库、缓存和消息中间件等。下面是对 Redis 的详细解析&#xff0c;包括其基本特性、数据结构、应用场景、安装及配置等方面的内容。 一、Redis 基本特性 键值存储&#xff1a;Redis 将数据存储在内存…

万龙觉醒免费辅助,自动打金挂机脚本!VMOS云手机辅助开局发育攻略!

《万龙觉醒》作为一款策略类手游&#xff0c;玩家需要在多个方面进行资源管理和战斗部署。为了更加高效地进行游戏&#xff0c;推荐使用VMOS云手机。通过VMOS云手机&#xff0c;你可以体验到游戏专属定制版的云手机&#xff0c;它内置游戏安装包&#xff0c;省去了重新下载安装…

李沐关于大模型应用及职业发展的分享

前几天看了 李沐 在上海交大做的一个 分享 &#xff0c; 主要分享了他对于大模型的一些看法和他个人的经历。 我很喜欢李沐&#xff0c;技术厉害&#xff0c;看起来比较接地气&#xff0c;录制的 课程 也比较容易看懂。 大模型的应用 下面这张图是他对当前大模型应用的看法。…

旅游景区生活污水处理设备处理工艺和用途

诸城市鑫淼环保小编带大家了解一下旅游景区生活污水处理设备处理工艺和用途 旅游景区生活污水处理设备根据处理工艺和用途的不同&#xff0c;可分为多种类型&#xff1a; 物理处理设备&#xff1a;主要包括格栅、沉砂池、沉淀池等。这些设备通过物理方法去除污水中的固体物质、…

【Qt】Qt音频

Qt 音频 在 Qt 中&#xff0c;⾳频主要是通过 QSound 类来实现。但是需要注意的是 QSound 类只⽀持播放 wav 格式的⾳频⽂件。也就是说如果想要添加⾳频效果&#xff0c;那么⾸先需要将 ⾮wav格式 的⾳频⽂件转换为 wav 格式。 【注意】使⽤ QSound 类时&#xff0c;需要添加模…

Unity3D ARPG(动作角色扮演游戏)设计与实现详解

动作角色扮演游戏&#xff08;Action Role-Playing Game, ARPG&#xff09;结合了传统角色扮演游戏&#xff08;RPG&#xff09;的深度与动作游戏&#xff08;Action Game&#xff09;的即时反应和流畅战斗体验。Unity3D 作为一款强大的跨平台游戏开发引擎&#xff0c;为开发者…

go--知识点

Go 语言遵循简洁、明确的设计原则&#xff0c;因此它没有类似的魔法函数机制。Go 语言中有一些特性可以起到类似魔法函数的效果&#xff0c;例如init() 函数。 Go 中有一个特别的函数 init()&#xff0c;它会在包初始化时自动调用&#xff0c;而无需显式调用。每个包可以定义多…

分类学习器(Classification Learner App)MATLAB

在MATLAB中&#xff0c;分类学习器用于构建和评估分类模型。MATLAB提供了一些工具和功能&#xff0c;帮助你进行分类任务&#xff0c;例如分类学习器应用程序、统计和机器学习工具箱中的函数等。 数据集介绍 不同的人被要求在平板电脑上写字母"J"、“V"和&quo…

list的简单实现

文章目录 前言list接口介绍构造函数迭代器常用容量操作元素访问插入删除头插尾插任意位置插入删除 其他常用操作 list简单实现框架构造析构插入emplace插入insert插入 删除迭代器操作符重载 前言 STL中的list是一个双向链表容器&#xff0c;适用于需要频繁插入和删除操作的场景…

Qt/C++开源项目 TCP客户端调试助手(源码分享+发布链接下载)

这是一个TCP客户端调试助手&#xff0c;具有简洁直观的界面&#xff0c;用户能够方便地测试TCP协议的通信功能&#xff0c;并可同时作为客户端与服务器端使用。以下是该程序的功能特点及用途介绍&#xff1a; 功能特点&#xff1a; TCP客户端与服务器调试&#xff1a;支持同时…

docker-compose安装mysql8集群

我这里一主两从mysql数据库集群,mysql镜像版本是8.0.39 如下 如下&#xff1a; [rootVM-20-8-centos mysqlData]# docker-compose ps NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS mysql-master …

vue2中的$watch--需要取消监听的场景

在开发过程中&#xff0c;有时我们需要取消watch监听器。 我们可以使用$watch方法来手动添加watch监听器&#xff0c;并且可以从组件实例中移除它。 这个方法的第一个参数是要监听的数据的名称&#xff0c;而第二个参数则表示要执行的回调函数。 export default {data() {retu…

Linux:从入门到放弃

目录 一、基础巩固Linux&#xff1a;常用命令 二、实战应用Linux&#xff1a;CentOS7基础配置Linux&#xff1a;CentOS7安装MySQL 三、常见问题Linux&#xff1a;yum源失效问题 一、基础巩固 Linux&#xff1a;常用命令 二、实战应用 Linux&#xff1a;CentOS7基础配置 Lin…

9.7(UDP局域网多客户端聊天室)

服务器端 #include<myhead.h> #define SERIP "192.168.0.132" #define SERPORT 8888 #define MAX 50 //定义用户结构体 typedef struct{struct sockaddr_in addr;int flag; }User;User users[MAX];//用户列表void add_user(struct sockaddr_in *client){// 检…

MFC工控项目实例之十三从文件读写板卡信号名称

承接专栏《MFC工控项目实例之十二板卡测试信号输出界面》 1、在BoardTest.h文件中添加代码 class CBoardTest : public CDialog {public:CBoardTest(CWnd* pParent NULL); // standard constructor... CString NO_Combox[16]; CString strTemp[16];//数据项名称 CString st…

鸿蒙(API 12 Beta6版)图形【NativeImage开发指导 (C/C++)】方舟2D图形服务

场景介绍 NativeImage是提供Surface关联OpenGL外部纹理的模块&#xff0c;表示图形队列的消费者端。开发者可以通过NativeImage接口接收和使用Buffer&#xff0c;并将Buffer关联输出到OpenGL外部纹理。 针对NativeImage&#xff0c;常见的开发场景如下&#xff1a; 通过Nati…