CUDA int128相乘是怎么实现的

CUDA int128相乘是怎么实现的

  • 一.指令对应关系
    • 1.cuda C代码
    • 2.PTX代码[二个int64]
    • 3.SASS指令[多个u32]
  • 二.复现过程

CUDA int128相乘是怎么实现的

一.指令对应关系

1.cuda C代码

clock_t t0=clock64();
__prof_trigger(0);
int128_t r4=r2*r3;  //二个int128_t相加
__prof_trigger(1);
clock_t t1=clock64();

2.PTX代码[二个int64]

mov.u64 %rd1, %clock64;
.loc    1 52 5
pmevent 0;
.loc    1 53 5
mul.hi.u64 %rd9, %rd8, %rd7;
mul.wide.u32 %rd10, %r5, %r5;
add.s64 %rd11, %rd9, %rd10;  //二个s64相加
mul.lo.s64 %rd12, %rd7, %rd7;
add.s64 %rd13, %rd11, %rd12; //
mul.lo.s64 %rd14, %rd8, %rd7;
.loc    1 54 5
pmevent 1;
.loc    1 55 5
mov.u64 %rd2, %clock64;

3.SASS指令[多个u32]

/*0070*/                   CS2R R12, SR_CLOCKLO ;
/*0080*/                   PMTRIG 0x1 ;
/*0090*/                   IMAD.WIDE.U32 R4, P0, R11, R9, RZ ;
/*00a0*/                   ULDC.64 UR4, c[0x0][0x118] ;
/*00b0*/                   IMAD.WIDE.U32 R2, R11, R8, RZ ;
/*00c0*/                   MOV R6, R5 ;
/*00d0*/                   IMAD.X R7, RZ, RZ, RZ, P0 ;
/*00e0*/                   IADD3 R0, P0, R3, R4, RZ ;
/*00f0*/                   IMAD.WIDE.U32.X R4, RZ, R9, R6, P0 ;
/*0100*/                   IADD3 R6, P0, R1, c[0x0][0x20], RZ ;
/*0110*/                   IMAD R7, R9, R8, RZ ;
/*0120*/                   IMAD.WIDE.U32 R4, R11, R11, R4 ;
/*0130*/                   IMAD R17, R8.reuse, R9, R7 ;
/*0140*/                   IMAD.WIDE.U32 R8, R8, R8, R4 ;
/*0150*/                   IMAD.X R7, RZ, RZ, c[0x0][0x24], P0 ;
/*0160*/                   IADD3 R17, R9, R17, RZ ;
/*0170*/                   PMTRIG 0x2 ;
/*0180*/                   CS2R R14, SR_CLOCKLO ;

二.复现过程

tee cuda_types.cu<<-'EOF'
#include <iostream>
#include <cuda_runtime.h>
#include <iostream>
#include <vector>
#include <stdio.h>
#include <assert.h>
#include <cstdio>
#include <cuda.h>
#include <cassert>
#include <cstdint>
#include <type_traits>
typedef __int128 int128_t;
typedef unsigned __int128 uint128_t;
__host__ __device__ constexpr uint128_t create_uint128(uint32_t le0,uint32_t le1,uint32_t le2,uint32_t le3) {return (uint128_t)le0 | (uint128_t)le1 << 32 | (uint128_t)le2 << 64 |(uint128_t)le3 << 96;
}
__host__ __device__ constexpr int128_t create_int128(uint32_t le0, uint32_t le1,uint32_t le2,uint32_t le3) {return (int128_t)create_uint128(le0, le1, le2, le3);
}    
__host__ __device__ constexpr uint128_t create_uint128(uint64_t le0,uint64_t le1) {return (uint128_t)le0 | (uint128_t)le1 << 64;
}    
__host__ __device__ constexpr int128_t create_int128(uint64_t le0,uint64_t le1) {return (int128_t)create_uint128(le0, le1);
}
#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(uint32_t *addr)
{unsigned int tid  = threadIdx.x + blockIdx.x * blockDim.x;uint64_t r0=tid*2;uint64_t r1=tid*r0;int128_t r2=create_int128(r0,r1);int128_t r3=create_int128(r1,r2);clock_t t0=clock64(); //用来标记ptx和sass指令__prof_trigger(0);    //用来标记ptx和sass指令int128_t r4=r2*r3;__prof_trigger(1);    //用来标记ptx和sass指令clock_t t1=clock64(); //用来标记ptx和sass指令addr[tid]=(uint32_t)r4;addr[tid+4]=(uint32_t)(r4>>32);addr[tid+8]=(uint32_t)(r4>>64);addr[tid+12]=(uint32_t)(r4>>96);printf("%lld\n",t1-t0);
}int main(int argc,char *argv[])
{int deviceid=0;cudaSetDevice(deviceid);  int block_count=28;int block_size=32*4;int thread_size=block_count*block_size;{uint32_t *addr;CHECK_CUDA(cudaMalloc(&addr, thread_size*4));kernel<<<block_count, block_size>>>(addr);CHECK_CUDA(cudaDeviceSynchronize());}    
}
EOF
/usr/local/cuda/bin/nvcc -std=c++17 -arch=sm_86 \-o cuda_types cuda_types.cu -I /usr/local/cuda/include -L /usr/local/cuda/lib64 -lcuda
/usr/local/cuda/bin/cuobjdump --dump-ptx ./cuda_types
/usr/local/cuda/bin/cuobjdump --dump-sass ./cuda_types

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

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

相关文章

Android Glide:让图片加载从未如此简单

在 Android 开发中,图片加载一直是一个关键环节。无论是从网络还是本地加载图片,都需要考虑到性能、内存管理和用户体验等多个方面。而在这方面,Glide 成为了众多开发者的首选库之一。本文将带你深入了解 Glide 的强大之处,并介绍如何在项目中快速集成和使用 Glide。 为什…

外包干了三年,快要废了。。。

先简单说一下自己的情况&#xff0c;普通本科&#xff0c;在外包干了3年多的功能测试&#xff0c;这几年因为大环境不好&#xff0c;我整个人心惊胆战的&#xff0c;怕自己卷铺盖走人了&#xff0c;我感觉自己不能够在这样蹉跎下去了&#xff0c;长时间呆在一个舒适的环境真的会…

算法刷题:300. 最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

300. 最长递增子序列 1.dp定义&#xff1a;dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度 2.递推公式&#xff1a;if (nums[i] > nums[j]) dp[i] max(dp[i], dp[j] 1); 注意这里不是要dp[i] 与 dp[j] 1进行比较&#xff0c;而是我们要取dp[j] 1的最大值…

JAVA 的excel数据批量导入解析 现在都用什么API工具 Apache POI 、EasyExcel 、easypoi有什么区别

&#x1f4dd;个人主页&#x1f339;&#xff1a;个人主页 ⏩收录专栏⏪&#xff1a;SpringBoot &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339;&#xff0c;让我们共同进步&#xff01; 在Java中&#xff0c;处理Excel数据批量导入解析时&#xff0c;常…

高空抛物检测算法的应用场景解析

高空抛物事件频发&#xff0c;对公众安全构成严重威胁。无论是居民区还是商业中心&#xff0c;从高层建筑中丢弃物品都可能导致人员伤亡和财产损失。传统的监控手段多以事后追溯为主&#xff0c;无法在事发时及时预警和干预。为应对这一难题&#xff0c;视觉分析技术的发展为高…

全国历年高考真题2008-2024

目录 分享链接&#xff1a; ⬇️⬇️⬇️ 点击下载

单元测试之mock使用

一、简介 一般程序中A类的m1方法调用B类的m2方法&#xff0c;而B类的m2方法又调用了C类的m3方法以此类推等等&#xff0c;而其中的某个方法的一些数据又需要调用其它服务或者查询数据库&#xff0c;一般单元测试只针对某个功能进行测试&#xff0c;但是如上面的情况在做单元测试…

Day9 | Java框架 | SpringBoot

Day9 | Java框架 | SpringBoot SpringBoot简介入门程序概述起步依赖 基础配置配置文件格式&#xff1a;3种yaml语法规则yaml数据读取三种格式 多环境启动配置文件参数命令行参数多环境开发控制&#xff1a;Maven & SpringBoot 多环境兼容 配置文件分类&#xff1a;4种 整合…

蓝桥杯4. Fizz Buzz 经典问题

题目描述 给定一个整数 NN&#xff0c;从 1 到 NN 按照下面的规则返回每个数&#xff1a; 如果这个数被 3 整除&#xff0c;返回 Fizz。如果这个数被 5 整除&#xff0c;返回 Buzz如果这个数能同时被 3 和 5 整除&#xff0c;返回 FizzBuzz。如果这个数既不能被 3 也不能被 5…

本地部署Llama 3.1大模型

Meta推出的Llama 3.1系列包括80亿、700亿、4050亿参数版本&#xff0c;上下文长度扩展至12.8万tokens&#xff0c;并增加了对八种语言的支持。 部署模型需要用到Ollama的一个工具&#xff0c;访问官方网站https://ollama.com 点击下载&#xff0c;选择下载你对应的操作系统下…

【无标题】Efinity 0基础进行流水灯项目撰写(FPGA)

文章目录 前言一、定义概念 缩写1. 二、性质1.2. 三、使用步骤编译常见错误1. 没加分号2. end 写多了 编译成功的标志总结参考文献 前言 数电课设 使用 FPGAIDE 使用 Efinity 一、定义概念 缩写 1. 二、性质 1. 2. 三、使用步骤 python代码块matlab代码块c代码块编译…

C# HttpClient 实现HTTP Client 请求

为什么? C# httpclient get 请求和直接浏览器请求结果不一样 为了测试一下HTTP接口的,用C# HttpClient实现了HTTP客户端,用于从服务端获取数据。 但是遇到了问题:C# httpclient get 请求和直接浏览器请求结果不一样 初始代码如下: using var client = new HttpClient()…

手把手带你拿捏C指针(2)(含冒泡排序)

文章目录 一、数组名的理解二、使用指针访问数组三、一维数组传参本质四、冒泡排序五、二级指针六、指针数组七、指针数组模拟二维数组 一、数组名的理解 在上⼀个章节我们在使⽤指针访问数组的内容时&#xff0c;有这样的代码&#xff1a; int arr[10] {1,2,3,4,5,6,7,8,9,…

工信部【信创认证】全面解读,包含信创集成项目管理师,信创规划管理师等

行业背景 国资委发布79号文件&#xff1a;详细规划了中央企业和国有企业信创国产化的实施路径和时间表&#xff0c;明确提出了到2027年100%完成信创“替代”的宏伟目标。这一政策不仅涵盖了芯片、基础软件、操作系统、中间件等重要领域&#xff0c;更意味着从2023年起&#xf…

微信小程序能不能有一种公共的分包,能被普通的分包引用其资源?(内有解决方案)

微信小程序中的跨分包引用与独立分包&#xff1a;优化加载速度和资源复用的利器 微信小程序开发过程中&#xff0c;开发者常常面临如何优化小程序加载速度、减少重复代码和提高资源复用率的问题。微信小程序提供了一些新的技术特性&#xff0c;比如跨分包引用和独立分包分包异…

5天涨粉3W!26个视频12.2W粉!AI做这种视频这么火嘛?

前几天刷到一个AI视频的账号&#xff0c;当时刷到时候才9W粉丝&#xff0c;今天又刷到他&#xff0c;已经12.2W了&#xff01;这涨粉速度&#xff0c;简直了&#xff01;&#xff01; 26个视频&#xff0c;12.2万粉丝 在这个看脸的时代&#xff0c;内容创作者们为了吸引眼球&a…

3.js - 着色器设置点材质(螺旋星系特效)

上图 着色器设置点材质时&#xff0c;在顶点着色器中&#xff0c;最好设置gl_PointSize&#xff0c;不然看不到你在页面中添加的点 main.js import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControlsimport gsap from gsapimp…

【截图服务 +打包】pkg打包 puppeteer

目录 最后结论 windows打包成服务 定制executablePath 用程序来查找chrome.exe 代替上面的写配置文件 服务遇到的问题 使用java开一个线程启动 遇到的问题与解决 版本匹配问题 打出包后的运行报错问题 linux下的安装 安装n 库缺少 程序运行后的报错 制作 运行报…

化工机械如何精准地进行网络营销推广?

合作咨询联系竑图 hongtu201988 化工机械行业该如何做网络推广&#xff0c;让销量和利润都有明显的提升呢&#xff1f;湖南竑图网络来为大家分析分析&#xff1a; 一、产品的用户是谁&#xff1f; 在传统行业中&#xff0c;用户群体的多样性不容忽视。比如机械设备有很多种&am…

Java 后端接口入参 - 联合前端VUE 使用AES完成入参出参加密解密

加密效果&#xff1a; 解密后的数据就是正常数据&#xff1a; 后端&#xff1a;使用的是spring-cloud框架&#xff0c;在gateway模块进行操作 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30…