You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
程 指 南 , 版<br />
<strong>NVIDIA</strong> <strong>CUDA</strong><br />
计 算 统 一 设 备 架 构<br />
编 程 指 南<br />
版 本 2.0<br />
6 / 7 / 2008<br />
<strong>CUDA</strong> 编<br />
i<br />
本 2.0
ii <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
目<br />
录<br />
1<br />
2 3 第<br />
第 4<br />
iii<br />
.......................................................................................................................................................... vi<br />
................................................................................................................................................... 1<br />
1.1 ............................................................................................................... 1<br />
1.2<br />
并 编 模<br />
GPU: ........................................................................................... 1<br />
1.3 .................................................................................................................................................. 3<br />
度 并 行 化 的 多 线 程 、 众 核 处 理 器 图 表 目<br />
...........................................................................................................................................<br />
录<br />
4<br />
<strong>CUDA</strong>:<br />
2.1 ..........................................................................................................................................<br />
介<br />
4<br />
2.2 ...................................................................................................................................... 6<br />
2.3 ..............................................................................................................................................<br />
可<br />
7<br />
伸 缩 行 程 型 高<br />
器 层 次 结 构 文 档 结<br />
2.4<br />
构<br />
...................................................................................................................................................... 8<br />
2.5 ..................................................................................................................................................<br />
备 章<br />
9<br />
型<br />
GPU ....................................................................................................................................... 10<br />
3.1<br />
栈 线<br />
SIMT<br />
程<br />
...................................................................................<br />
层<br />
10<br />
次 结 构 存 宿 主 和 设<br />
3.2 ................................................................................................................................................ 12<br />
3.3 ................................................................................................................................................<br />
储<br />
享 存 储 器 的 一 组 多 处 理 器 软<br />
12<br />
件<br />
......................................................................................................................... 13<br />
4.1 C<br />
设 备 计<br />
................................................................................................................................<br />
算<br />
13<br />
能 力 实 具 有 片<br />
4.2<br />
上<br />
................................................................................................................................................ 13<br />
4.2.1 .........................................................................................................................<br />
现 共<br />
展 多<br />
13<br />
个<br />
4.2.1.1 __device__........................................................................................................................ 13<br />
4.2.1.2<br />
扩 展 模<br />
__global__<br />
式<br />
........................................................................................................................<br />
切<br />
14<br />
换<br />
4.2.1.3 __host__............................................................................................................................ 14<br />
4.2.1.4 编<br />
..................................................................................................................................<br />
程<br />
14<br />
4.2.2 ......................................................................................................................... 14<br />
语<br />
4.2.2.1<br />
言<br />
__device__........................................................................................................................<br />
语<br />
14<br />
言<br />
4.2.2.2<br />
函<br />
__constant__<br />
数<br />
..................................................................................................................... 14<br />
4.2.2.3 __shared__........................................................................................................................ 15<br />
4.2.2.4<br />
章<br />
..................................................................................................................................<br />
口<br />
15<br />
4.2.3 ..................................................................................................................................... 16<br />
的 扩<br />
4.2.4<br />
类<br />
.....................................................................................................................................<br />
型<br />
16<br />
4.2.4.1 gridDim............................................................................................................................. 16<br />
限<br />
4.2.4.2<br />
定<br />
blockIdx<br />
符<br />
............................................................................................................................<br />
变<br />
16<br />
4.2.4.3 blockDim .......................................................................................................................... 16<br />
4.2.4.4 threadIdx ........................................................................................................................... 16<br />
4.2.4.5 warpSize ........................................................................................................................... 17<br />
4.2.4.6 17<br />
制<br />
4.2.5<br />
量<br />
17<br />
4.2.5.1 __noinline__ ..................................................................................................................... 17<br />
4.2.5.2 #pragma unroll.................................................................................................................. 17<br />
限 行 配<br />
4.3<br />
置 内 执<br />
18<br />
4.3.1 18<br />
量 变 置<br />
使<br />
4.3.1.1<br />
限 通 进<br />
char1、uchar1、char2、uchar2、char3、uchar3、char4、uchar4、short1、ushort1、short2、<br />
内<br />
简<br />
程 模 编<br />
应 用 程 序 编 程 接<br />
目<br />
录 ..........................................................................................................................................................<br />
置 向 量 类<br />
double2 ............................................................................................................................................ 18<br />
4.3.1.2 dim3 18<br />
4.3.2 18<br />
4.3.3 18<br />
4.3.4 19<br />
4.3.4.1 19<br />
类<br />
4.3.4.2 19<br />
数 纹 计 运 纹<br />
制 ..................................................................................................................................<br />
<strong>CUDA</strong> 编<br />
iii<br />
用 NVCC<br />
.............................................................................................................. 译 编 行<br />
.................................................................................................................................... 行 时 组 件 运 用<br />
型 .............................................................................................................................<br />
型 ........................................................................................................................<br />
ushort2、short3、ushort3、short4、ushort4、int1、uint1、int2、uint2、int3、uint3、int4、uint4、<br />
long1、ulong1、long2、ulong2、long3、ulong3、long4、ulong4、float1、float2、float3、float4、<br />
..................................................................................................................................... 数 函 学<br />
2.0 南 , 版 本 指 程<br />
..................................................................................................................................... 数 理 类 函 时<br />
型 .....................................................................................................................................<br />
.................................................................................................................. 考 声 明 参 理<br />
...................................................................................................... 纹 理 参 考 属 性 时 行
第 5<br />
4.4<br />
4.5<br />
设<br />
宿<br />
5.1 指<br />
4.3.4.3 20<br />
.................................................................................................................................... 20<br />
4.4.1 ..................................................................................................................................... 20<br />
4.4.2 ..................................................................................................................................... 20<br />
4.4.3 ..................................................................................................................................... 21<br />
同 步 数<br />
4.4.3.1 .................................................................................................. 21<br />
备<br />
4.4.3.2<br />
运<br />
<strong>CUDA</strong><br />
行<br />
...............................................................................................<br />
时<br />
21<br />
组<br />
4.4.4<br />
件<br />
..................................................................................................................................... 21<br />
4.4.5 Warp<br />
器 数<br />
vote<br />
学<br />
........................................................................................................................... 22<br />
的 纹 理 原 子 函 数 纹 理<br />
.................................................................................................................................... 22<br />
4.5.1 .....................................................................................................................................<br />
线<br />
22<br />
性<br />
4.5.1.1<br />
存<br />
..................................................................................................................................<br />
储<br />
22<br />
4.5.1.2 .............................................................................................................................. 23<br />
来 自 数 组<br />
设 备 函 数<br />
4.5.1.3 OpenGL ........................................................................................................... 23<br />
器 主<br />
4.5.1.4<br />
运<br />
Direct3D<br />
行<br />
..........................................................................................................<br />
时<br />
23<br />
4.5.1.5 .................................................................................................................. 23<br />
4.5.2<br />
组<br />
API.................................................................................................................................<br />
件<br />
24<br />
一 般 概 念<br />
并 发 执 行 存 储<br />
4.5.2.1 .............................................................................................................................. 24<br />
时 4.5.2.2 .......................................................................................................................... 24<br />
4.5.2.3 ...................................................................................................................... 25<br />
4.5.2.4<br />
互<br />
..............................................................................................................................<br />
操<br />
26<br />
作 性 异 步<br />
管 理 运 行<br />
4.5.2.5 .......................................................................................................................... 26<br />
理 初<br />
4.5.2.6<br />
始<br />
..................................................................................................................<br />
化<br />
27<br />
4.5.2.7 OpenGL ...........................................................................................................<br />
理 设<br />
28<br />
备<br />
4.5.2.8 Direct3D .......................................................................................................... 28<br />
管 理 存 储 器 流 管<br />
4.5.2.9 ........................................................................................... 29<br />
作 性 事<br />
4.5.3<br />
件<br />
API.............................................................................................................................<br />
管<br />
30<br />
4.5.3.1 .............................................................................................................................. 30<br />
备 模 拟 模 式 进 行 调 试 纹<br />
4.5.3.2<br />
理<br />
..........................................................................................................................<br />
参<br />
30<br />
考 互 操<br />
4.5.3.3 ...................................................................................................................... 30<br />
使<br />
4.5.3.4<br />
用<br />
..........................................................................................................................<br />
设<br />
31<br />
4.5.3.5 .......................................................................................................................... 31<br />
驱<br />
4.5.3.6<br />
动<br />
......................................................................................................................<br />
程<br />
32<br />
序 初 始 化<br />
制 设 备<br />
4.5.3.7 .............................................................................................................................. 33<br />
器 管 理 上<br />
4.5.3.8<br />
下<br />
..........................................................................................................................<br />
文<br />
33<br />
4.5.3.9 .................................................................................................................. 34<br />
模<br />
4.5.3.10<br />
块<br />
OpenGL ......................................................................................................... 34<br />
执 行 控<br />
考 管 理 存 储<br />
4.5.3.11 Direct3D ........................................................................................................ 35<br />
流<br />
.........................................................................................................................................<br />
管<br />
36<br />
理<br />
................................................................................................................................................ 36<br />
5.1.1<br />
性 事<br />
............................................................................................................................. 36<br />
件 管 理 5.1.1.1 .......................................................................................................................... 36<br />
纹 理 参 互<br />
5.1.1.2<br />
操<br />
......................................................................................................................<br />
作<br />
37<br />
5.1.1.3 ...................................................................................................................... 37<br />
令 南<br />
5.1.1.4 38<br />
制 流 令 性 能<br />
指 令 指<br />
5.1.2 38<br />
令<br />
5.1.2.1 38<br />
5.1.2.2<br />
数<br />
44<br />
5.1.2.3 44<br />
学 吞<br />
5.1.2.4 44<br />
指<br />
5.1.2.5 44<br />
5.1.2.6<br />
控<br />
49<br />
50<br />
存 量 吐<br />
同 器 储<br />
本 全 存<br />
寄 共 纹 常<br />
性 能 指 章<br />
5.2 每<br />
<strong>CUDA</strong> 性 存 储 器 的 纹 理 与 来 自 线 自<br />
.................................................... 纹 理 的 组<br />
iv <strong>CUDA</strong> 编<br />
.......................................................................................................................... 令 指 步<br />
......................................................................................................................... 带 宽 器 储<br />
...................................................................................................................... 储 器 存 地<br />
...................................................................................................................... 储 器 存 局<br />
2.0 南 , 版 本 指 程<br />
...................................................................................................................... 储 器 存 量<br />
...................................................................................................................... 器 享 存 储 理<br />
器 ......................................................................................................................<br />
.............................................................................................................................. 器 存<br />
................................................................................................................................ 的 线 程 数 量 块 个
程 指 南 , 版<br />
5.3<br />
5.4<br />
5.5<br />
6.1<br />
整 章 宿<br />
6.2<br />
6.3<br />
纹<br />
源 概<br />
50<br />
......................................................................................... 51<br />
................................................................................................................................ 51<br />
................................................................................................................................. 53<br />
........................................................................................................................................................ 53<br />
............................................................................................................................................ 54<br />
器 读 取 的 对 比 体 性 能 优 化 策 略 例 述 理 拾 取<br />
............................................................................................................................................<br />
与<br />
55<br />
6.3.1 Mul()............................................................................................................................................<br />
全<br />
55<br />
局<br />
6.3.2<br />
或<br />
Muld()..........................................................................................................................................<br />
常<br />
55<br />
.........................................................................................................................................<br />
量 储 存<br />
范 明 说 码 代 单 清 6<br />
A 57<br />
第<br />
A.1 ............................................................................................................................................... 57<br />
A.1.1 1.0 ................................................................................................................ 57<br />
A.1.2 1.1 ................................................................................................................ 58<br />
A.1.3 1.2 ................................................................................................................ 58<br />
A.1.4 1.3 ................................................................................................................ 58<br />
附 录 一<br />
A.2<br />
范<br />
............................................................................................................................................... 58<br />
B ................................................................................................................................. 60<br />
技<br />
力 的 规 范 B.1 .................................................................................................................................... 60<br />
函 数 B.1.1 ......................................................................................................................... 60<br />
B.1.2 计<br />
.........................................................................................................................<br />
算<br />
62<br />
B.1.3 ..................................................................................................................................... 63<br />
能 浮<br />
B.2<br />
点<br />
.................................................................................................................................... 63<br />
附 录 标 准 通 用 B.2.1 ......................................................................................................................... 64<br />
B.2.2<br />
数 学 ......................................................................................................................... 65<br />
B.2.3 ..................................................................................................................................... 65<br />
C ......................................................................................................................................... 66<br />
点 函 数 设 备 运<br />
C.1 ................................................................................................................................................ 66<br />
C.1.1<br />
行 时 组 单<br />
atomicAdd() ................................................................................................................................ 66<br />
C.1.2 atomicSub()................................................................................................................................. 66<br />
C.1.3 atomicExch()............................................................................................................................... 66<br />
C.1.4 atomicMin() ................................................................................................................................ 66<br />
件<br />
C.1.5 atomicMax()................................................................................................................................ 67<br />
C.1.6 atomicInc() .................................................................................................................................. 67<br />
C.1.7 atomicDec()................................................................................................................................. 67<br />
C.1.8 atomicCAS() ............................................................................................................................... 67<br />
数 函 数 函 子 数 函 型 整 浮 度 精 双 学 数 原 录 附<br />
阵 乘 法 示 矩<br />
规 般 规 术<br />
能 算<br />
C.2 位<br />
D.1 最 纹<br />
D.2<br />
D.3 表 线<br />
67<br />
C.2.1 atomicAnd() ................................................................................................................................ 67<br />
C.2.2 atomicOr()................................................................................................................................... 68<br />
C.2.3 atomicXor()................................................................................................................................. 68<br />
69<br />
69<br />
70<br />
70<br />
.................................................................................................................... 设 备 间 的 数 据 传 输 和 主<br />
............................................................................................................................................ 函 数 辑 逻<br />
附<br />
......................................................................................................................................... 取 拾 理<br />
<strong>CUDA</strong> 编<br />
v<br />
录 D<br />
........................................................................................................................................... 采 样 性 过 点 近<br />
滤 ...............................................................................................................................................<br />
................................................................................................................................................... 找 查<br />
本 2.0
图 表 目 录<br />
CPU<br />
1-2. 图 和<br />
GPU<br />
2-1. .......................................... 程 块 网 格 图 中<br />
线<br />
存<br />
异<br />
的 更 多 晶 体 管 用 于 数 据 处 的<br />
...... ......... ..... .............. .....................2 宽<br />
...... .............. .......... .............. .............. .....................2 理<br />
....... ..................... ...................................................6<br />
器 层 次 结 储<br />
<strong>CUDA</strong><br />
................................................................... 型 软<br />
硬<br />
库<br />
2-2.<br />
2-3.<br />
2-4.<br />
3-1. 4-1. 5-1.<br />
5-2. 存 图<br />
................................. .............. ...................................................................7 构<br />
............. .............. .............. ....................................8<br />
................ .............. .............. ..................... .............. .. ...................................9 栈<br />
.............. ...........................................11<br />
......................................................... 理<br />
.............. ....... ......... ...........................31<br />
................... 例<br />
.............. .............. .............. .. ........ ..40<br />
.... 例<br />
............................................... 程 件 件 模 构 编<br />
文 管 储 器 合 并 后 的 存 储 器 访 问 模 式 示 为 计 算 能 力 设 备 进 行 存 储 器 合 并 的 全 局 存 储 器 访 问 模 式 示 上 下<br />
的 或 未<br />
计<br />
无<br />
无<br />
1.0<br />
或 是<br />
41<br />
... .42 例<br />
1.1<br />
.............. .............. .............. ...............48<br />
用 广 播 机 制 的 共 享 存 储 器 读 取 访 问 模 式 示 有<br />
5-8. 使 图<br />
矩<br />
..... .............. ............ .. .. .........43 例<br />
.............. .............. .............. .............. ......46<br />
.............. .............. .............. .............. ......47<br />
... .............. .............. .............. ...............49 例<br />
........................................................... .............. .............. ....................................53 法<br />
图 1-1.<br />
GPU<br />
每 秒 浮 点 运 算 次 数 和 存 储 器 带<br />
图 5-3.<br />
1.0 算 能 力 是 计 为<br />
1.1<br />
设 备 进 行 存 储 器 合 并 的 全 局 存 储 器 访 问 模 式 示<br />
图 5-5.<br />
... 体 冲 突 的 共 享 存 储 器 访 问 模 式 示 例 储 存<br />
图 5-4.<br />
1.2 力 为 能 算<br />
更 高 的 设 备 的 全 局 存 储 器 访 问 示<br />
图 5-6.<br />
... 体 冲 突 的 共 享 存 储 器 访 问 模 式 示 例 储 存<br />
图 5-7.<br />
......... 体 冲 突 的 共 享 存 储 器 访 问 模 式 示 例 储 存<br />
图 6-1.<br />
阵 乘<br />
vi <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
核 (manycore) 众<br />
程 指 南 , 版<br />
图<br />
所 已<br />
(language<br />
(runtime<br />
第 1 章 简 介<br />
1.1 <strong>CUDA</strong>: 可 伸 缩 并 行 编 程 模 型<br />
<strong>CUDA</strong> 是<br />
<strong>CUDA</strong> 的<br />
和<br />
GPU 的<br />
种 并 行 编 程 模 型 和 软 件 环 境 , 用 于 应 对 这 种 挑 战 。 而 对 于 熟 绝 一<br />
语<br />
图<br />
定 律 , 其 并 行 性 还 会 不 断 扩 展 。 这 给 我 们 带 来 了 严 峻 的 挑 战 —— 我 们 需 要 开 发 出 可 透 明 地 扩 展 并 行 语 言 等 标 准 编 程 语 言 的 尔<br />
(barrier synchronization),<br />
CPU 核 多<br />
出 现 意 味 着 主 流 处 理 器 芯 片 已 进 入 并 行 时 代 。 此 外 , 根 据 摩<br />
物 理 处 理 器 数 量 。<br />
时 通 过 在 任 何 可 用 处 理 器 内 核 上 处 理 各 子 问 题 来 支 持 透 明 的 可 伸 缩 性 : 因 而 , 编 译<br />
3D 应 用 软 件 , 以 利 用 日 益 增 加 处 理 器 内 核 数 量 , 这 种 情 况 正 如 行 性 以 支 持 配 备 各 种 数 量 的 内 核 的 众 的 性<br />
核 GPU。<br />
形 应 用 程 序 透 明 地 扩 展 其 并<br />
C<br />
核 心 有 三 个 重 要 抽 象 概 念 : 组 层 次 结 构 、 共 享 存 储 器 、 栅 障 同 步 悉<br />
些 抽 象 提 供 了 细 粒 度 的 数 据 并 行 和 线 程 并 行 , 嵌 套 于 粗 粒 度 的 数 据 并 行 和 任 务 并 行 之 中 。 它 们 将 指 导 程 序 员 将 问 题 为 可 独 立 处 理 的 粗 粒 度 子 问 题 , 再 细 分 成 细 粒 度 的 片 段 , 以 便 通 过 协 作 的 方 法 并 行 解 决 。 这 样 的 分 解 以 允 许 线 程 在 解 决 子 问 题 时 协 作 为 目 的 设 计 了 编 程 语 言 的 表 达 方 式<br />
expressivity), 同 这<br />
system) 需 程<br />
1.2 GPU: 高 度 并 行 化 的 多 线 程 、 众 核 处 理 器<br />
<strong>CUDA</strong> 员 来 说 , 迅 速 掌 握 序 程<br />
难 事 。 非<br />
C 程 序 员 来 说 , 它 们 只 是 于 对<br />
的 一 个 极 小 扩 展 。 言<br />
形 永 无 尽 头 的 需 求 , 可 编<br />
发 展 成 为 一 种 高 度 并 行 化 的<br />
<strong>CUDA</strong> 的 后<br />
序 可 以 在 任 何 数 量 的 处 理 器 内 核 上 执 行 , 只 有 运 行 时 系 统<br />
要 了 解<br />
多 线 程 、 众 核 处 理 器 , 具 有 杰 出 的 计 算 能 力 和 极 高 的 存 储 器 带 宽 , 如<br />
。 示<br />
<strong>CUDA</strong> 编<br />
1<br />
3D 足 消 费 者 对 实 时 、 高 清 晰 度 的 满 为<br />
程 GPU<br />
图 1-1<br />
本 2.0
和<br />
和<br />
之<br />
,GPU 专<br />
(flow 如 control),<br />
的<br />
专 为 计 算 密 集 型 、 高 度 并 行 化 的 的 设 计 将 更 多 晶 体 管 用 于 数 据 处 理 , 而 非 数 据 缓 存 所 示 。 宽<br />
CPU<br />
CPU<br />
宽 的 每 秒 浮 点 运 算 次 数 和 存 储 器 带 图 1-1.<br />
GPU<br />
图 1-2<br />
GPU 中<br />
GPU<br />
GPU 点 能 力 之 所 以 存 在 这 样 的 差 异 , 原 因 就 在 于 浮 间<br />
,GPU 而 设 计 , 上 图 显 示 的 正 是 这 种 情 况 , 因 而<br />
(caching) 和 流 控 制 算 计<br />
具 体 地 说 有 极 高 的 计 算 密 度 ( 数 学 运 算 与 存 储 器 操 作 的 比 率 )。 由 于 所 有 数 据 元 素 都 执 行 相 同 的 程 序 , 因 此 对 精 密 更<br />
2 <strong>CUDA</strong> 解 决 可 表 示 为 数 据 并 计 算 的 问 题 —— 在 许 多 数 据 元 素 上 并 行 执 行 的 程 序 , 具 流 控 制 的 要 求 高 ; 由 于 在 许 多 数 据 元 素 上 运 行 , 且 具 有 较 高 的 计 算 密 度 , 因 而 可 通 过 计 算 来 隐 藏 存 储 器 访 问 延 迟 , 而 不 必 使 用 较 大 的 数 据 缓 存 。 编<br />
图 1-2.<br />
中 的 更 多 晶 体 管 用 于 数 据 处 理<br />
2.0 南 , 版 本 指 程
渲<br />
程 指 南 , 版<br />
的<br />
第<br />
列 的<br />
(texture 的 fetching)<br />
介 。 运 行 时 简<br />
。<br />
。。<br />
编<br />
。<br />
应 架<br />
<strong>CUDA</strong> 编<br />
GPU 基<br />
1.3 文 档 结 构<br />
3D 来 加 速 计 算 。 在 染 中 , 大 量 的 像 素 顶 点 集 将 映 射 到 并 行 线 程 。 类 似 地 , 图 像 和 媒 体 处 理 应 用 程 序 ( 如 渲 染 图 像 的 后 期 处 理 、 视 频 编 码 和 解 码 、 图 像 缩 放 、 立 体 视 觉 和 模 式 识 别 等 ) 可 将 图 像 块 和 像 素 映 射 到 并 行 处 理 线 程 。 实 际 上 , 在 图 像 渲 染 和 处 理 领 域 之 外 的 许 多 算 法 也 都 是 通 过 数 据 并 行 处 理 加 速 的 —— 从 普 通 信 号 处 理 或 物 理 仿 真 一 直 到 计 算 金 融 或 计 算 生 物 学 。 模 型<br />
型 , 可 显 著 加 用 程 序 。 模 程<br />
数 据 并 行 处 理 会 将 数 据 元 素 映 射 到 并 行 处 理 线 程 。 许 多 处 理 大 型 数 据 集 的 应 用 程 序 都 可 使 用 数 据 并 行 编 程<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
附 第 章 列 给 提<br />
文 档 分 为 以 下 几 个 章 节 : 和 的 编 程 模 型 实 现 。 本<br />
API<br />
提 供 如 何 实 现 最 高 性 能 的 一 些 指 南 和<br />
过 一 些 简 单 示 例 代 码 概 况 之 前 各 章 的 内 容 供 各 种 设 备 的 技 术 规 范 支 持 的 数 学 函 数 中 通<br />
更 多 纹 理 拾 取 出<br />
GPU 型 非 常 适 合 利 用 模 程<br />
<strong>NVIDIA</strong> 能 力 。 最 新 一 代 的 行 并<br />
于 Tesla<br />
A 在 附 录 ( 构<br />
<strong>CUDA</strong> 以 查 看 所 有 支 持 可 中<br />
GPU<br />
<strong>CUDA</strong> 支 持 ), 表<br />
速 <strong>CUDA</strong><br />
1<br />
是 <strong>CUDA</strong><br />
GPU<br />
2<br />
<strong>CUDA</strong> 述 概<br />
3<br />
GPU 绍 介<br />
4<br />
<strong>CUDA</strong> 绍 介<br />
持 的 原 子 函 数 。 支<br />
细 节<br />
5<br />
录 D<br />
6<br />
录 C<br />
录 A<br />
录 B<br />
举 <strong>CUDA</strong><br />
举 <strong>CUDA</strong><br />
<strong>CUDA</strong> 编<br />
3<br />
本 2.0
中<br />
个<br />
线<br />
线 声<br />
的<br />
设<br />
的<br />
和<br />
相<br />
次 语<br />
语 (declaration 使 specifier),<br />
个<br />
block)。 这<br />
是<br />
是<br />
的<br />
中 变<br />
和<br />
z)<br />
相<br />
语 。<br />
此 ID。<br />
x,D y ) 的<br />
第 2 章 编 程 模 型<br />
<strong>CUDA</strong> 允<br />
言 的 一 种 扩 展 , 在 调 用 此 类 函<br />
言 函 数 只 执 行 一 次 的 方 式 不 同<br />
的<br />
// Kernel definition<br />
__global__ void vecAdd(float* A, float* B, float* C)<br />
{<br />
}<br />
符 定 限 明<br />
(kernel)<br />
许 程 序 员 定 义 被 称 为 内 核<br />
C<br />
int main()<br />
{<br />
}<br />
// Kernel invocation<br />
vecAdd(A, B, C);<br />
C 数 , 这 是 对 函 言<br />
N , 它 将 由 时 数<br />
<strong>CUDA</strong> 的 同 不<br />
N 行 执 行 并 程<br />
C 与 普 通 的 这 ,<br />
__global__ 义 内 核 时 , 需 要 使 用 定 在<br />
:<br />
种 全 新 的 一 用<br />
__global__ void vecAdd(float* A, float* B, float* C)<br />
{<br />
int i = threadIdx.x;<br />
C[i] = A[i] + B[i];<br />
}<br />
可<br />
<strong>CUDA</strong> 定 每 次 调 用 的 指 法<br />
数 : 程<br />
int main()<br />
{<br />
// Kernel invocation<br />
vecAdd(A, B, C);<br />
}<br />
) 每 个 线 程 都 会 执 行 一 次 两 两 相 加 运 算 的<br />
行 内 核 的 每 个 线 程 都 会 被 分 配 一 个 独 特 的 线 程 ID, 执<br />
threadIdx 内 置 的 过 通<br />
量 在 内 核 中 访 问<br />
2.1 线 程 层 次 结 构<br />
执<br />
线 程 层 次 结 构<br />
N 示 例 代 码 将 大 小 为 下 以<br />
A 量 向<br />
B 量 向<br />
C 并 将 结 果 存 储 在 向 量 , 加<br />
行 vecAdd(<br />
__global__ void matAdd(float A[N][N], float B[N][N],<br />
float C[N][N])<br />
{<br />
int i = threadIdx.x;<br />
int j = threadIdx.y;<br />
C[i][j] = A[i][j] + B[i][j];<br />
}<br />
int main()<br />
{<br />
// Kernel invocation<br />
dim3 dimBlock(N, N);<br />
matAdd(A, B, C);<br />
}<br />
:<br />
(thread<br />
C<br />
构 成 一 维 、 二 维 或 三 维 线 程 块 储 在 矩 阵 , 程 线<br />
有<br />
。<br />
供 了 一 种 自 然 的 方 法 , 可 为 一 个 域 中 的 各 元 素 提<br />
threadIdx 便 起 见 , 我 们 将 方 为<br />
3 一 个 包 含 为 置<br />
分 量 的 向 量 , 因 而 可 使 用 一 维 、 二 维 或 三 维 索 引 标 识<br />
y, z)<br />
+ yD<br />
+ yD x + zD x D y)。 x);<br />
x,D y,<br />
4 <strong>CUDA</strong> 编<br />
NxN 计 算 , 如 向 量 、 矩 阵 或 字 段 。 下 面 的 示 例 代 码 将 大 小 为 用 调<br />
A 阵 矩<br />
B 阵 矩<br />
加 , 并 将 结 果 存<br />
(x,y) 块 来 说 , 索 引 为 维 二<br />
ID 的 程 线<br />
(x<br />
(D 大 小 为 于 对<br />
D<br />
的 三 维 块 来 说 , 索<br />
2.0 南 , 版 本 指 程<br />
ID 的 索 引 与 其 线 程 程 线<br />
(D 接 的 对 应 关 系 : 对 于 一 维 块 来 说 , 两 者 是 相 同 的 ; 对 于 大 小 为 直 着<br />
(x, 为 引<br />
ID 程 的 线 的<br />
(x
程 指 南 , 版<br />
变<br />
(shared<br />
(intrinsic 内 function) 在 来 memory)<br />
(grid),<br />
所<br />
缓<br />
变 语<br />
将 每 个 线 程 处 理 一 个 矩 阵 元 素 , 这 与 之 前 完 全 相 同 。 线 程 块 需 要 独 立 执 行 : 必 须 能 够 以 任 意 顺 序 执 行 —— 能 够 并 行 或 串 行 执 行 。 这 种 独 立 性 需 求 允 许 为 任 意 数 量 的 处 理 器 内 核 安 排 线 程 块 , 从 而 使 程 序 员 能 够 编 写 出 可 伸 缩 的 代 码 。<br />
个 网 格 内 的 线 程 块 通 常 是 由 所 处 理 的 数 据 大 小 限 定 的 , 而 不 是 由 系 统 中 的 处 理 器 数 量 决 定 的 , 前 者 可 以 远 远 超 过 后 者 的 数 量 。 一<br />
建 函 数<br />
共 享 数 据 , 并 同 步 其 执 行 来 协 调 存<br />
屏 障 的 作 用 , 块 中 的 所 有 线 程 都 必 须 在 这 里 等 待 处 理 。 到<br />
__syncthreads() 起<br />
__syncthreads() 被<br />
个<br />
Tesla 架<br />
个 块 内 的 线 程 可 彼 此 协 作 , 一 些 共 享 存 储 器 储 器 访 问 。 更 具 体 地 说 , 可 以 通 过 调 一<br />
用 __syncthreads()<br />
像 L1<br />
内 核 中 指 定 同 步 点 ;<br />
__global__ void matAdd(float A[N][N], float B[N][N],<br />
float C[N][N])<br />
{<br />
int i = blockIdx.x * blockDim.x + threadIdx.x;<br />
int j = blockIdx.y * blockDim.y + threadIdx.y;<br />
if (i < N && j < N)<br />
C[i][j] = A[i][j] + B[i][j];<br />
}<br />
int main()<br />
{<br />
// Kernel invocation<br />
dim3 dimBlock(16, 16);<br />
dim3 dimGrid((N + dimBlock.x – 1) / dimBlock.x,<br />
(N + dimBlock.y – 1) / dimBlock.y);<br />
matAdd(A, B, C);<br />
}<br />
<strong>NVIDIA</strong> 内 核 的 有 限 存 储 器 资 源 限 制 了 每 个 块 的 线 程 数 量 。 在 构 中 , 一 个 线 程 块 最 多 可 以 包 但 一 个 内 核 函 数 能 由 多 个 大 小 相 同 的 线 程 块 执 行 , 因 而 线 程 总 数 应 等 于 每 个 块 的 线 程 数 乘 以 块 的 数 量 。 如 理<br />
blockDim<br />
器<br />
问 此 索 引 。 可 以 通 过 内 置 的 量 在 内 核 中 访 问 线 程 块 的 维 度 。 此 时 , 之 前 的 示 例 代 码 可 修 改 为 : 访 中<br />
的<br />
个<br />
实 现 有 效 的 协 作 , 共 享 存 储 器 被 设 计 为 靠 近 各 处 理 器 内 核 的 低 延 迟 存 储 , 这 很 存 , 设 计 为 轻 量 级 的 , 一 个 块 中 的 所 有 线 程 都 必 须 位 于 同 一 个 处 理 器 内 核 中 。 因 而 , 一 个 处 为<br />
含 512<br />
程 。 线<br />
这 些 块 被 组 织 为 一 个 一 维 或 二 维 线 程 块 网 格<br />
图 2-1<br />
该 网 格 的 维 度 由 。 示<br />
法 的<br />
blockIdx 个 参 数 指 定 。 网 格 内 的 每 个 块 多 可 由 一 个 一 维 或 二 维 索 引 标 识 , 可 通 过 内 置 的 一 第<br />
量 在 内 核<br />
16x16 随 机 选 择 了 大 小 为 们 我<br />
256 块 ( 即 包 含 程 线<br />
线 程 ), 此 外 创 建 了 一 个 网 格 , 它 具 有 足 够 的 块 ,<br />
<strong>CUDA</strong> 编<br />
5<br />
本 2.0
线 程 块 网 格<br />
(local (shared<br />
(constant<br />
(texture<br />
该 memory)。 每 memory),<br />
纹 对 于 同 一 个 应 用 程 序 启 动 的 内 核 而 言 , 全 局 、 常 量 和 纹 理 存 储 器 空 间 都 是 持 久 的 。 和 空 memory)<br />
所<br />
memory) 空<br />
2.2 存 储 器 层 次 结 构<br />
<strong>CUDA</strong><br />
存 储 器 线<br />
图 2-1.<br />
可 在 执 行 过 程 中 访 问 多 个 存 储 器 空 间 的 数 据 , 如 个 线 程 块 都 有 一 个 共 享 存 储 器 程<br />
示 。 每 个 线 程 都 有 一 个 私 有 的 本 地<br />
存 储 器 对 于 块 内 的 所 有 线<br />
间<br />
和 纹 理 存 储 器<br />
间 。 全 局 、 常 量 和 纹 理 存 储 器 空 间 经 过 优 化 , 适 于 不 同 的 存 储 器 用 途 ( 参<br />
图 2-2<br />
(global 是 可 见 的 , 并 且 与 块 具 有 相 同 的 生 命 周 期 。 最 终 , 所 有 线 程 都 可 访 问 同 一 个 全 局 存 储 器<br />
memory)。<br />
此 外 还 有 两 个 只 读 的 存 储 器 空 间 , 可 由 所 有 线 程 访 问 , 这 两 个 空 间 是 常 量 存 储 器 都 程<br />
( 参 见 第 4.3.4)。 滤<br />
见 第 5.1.2.1、5.1.2.3<br />
5.1.2.4)。<br />
理 存 储 器 也 为 某 些 特 殊 的 数 据 格 式 提 供 了 不 同 的 寻 址 模 式 以 及 数 据 过<br />
6 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
所<br />
,<strong>CUDA</strong><br />
(host)<br />
假<br />
memory)。 因 的<br />
之 间 的 数 据 传 输 。 器<br />
(device<br />
,<strong>CUDA</strong> 还<br />
线<br />
章<br />
存<br />
运 分<br />
上<br />
构<br />
上 语<br />
(device)<br />
(host<br />
(<strong>CUDA</strong> runtime) 来 和 memory)<br />
2.3 宿 主 和 设 备<br />
图 2-2.<br />
构 存 储 器 层 次 结 备 存 储 管 理 对 内 核 可 见 的 全 设<br />
外 器 局 、 常 量 和 纹 理 存 储 器 空 间 ( 详 见 此<br />
称 为 宿 主 存 储 器 行 时 )。 这 包 括 设 备 存 储 器 分 配 和 取 消 分 配 , 还 包 括 宿 主 和 设 备 存 储 别<br />
2-3 图 如<br />
设 <strong>CUDA</strong><br />
程 可 在 物 理 上 独 立 的 设 备<br />
语 言 程 序 的 宿 主 示<br />
而 , 一 个 程 序 通 过 调<br />
C , 此 类 设 备 作 为 运 行 行 执<br />
执 行 , 就 是 一 例 。 上<br />
协 处 理 器 存 在 。 比 如 , 内 核<br />
在 GPU<br />
C , 而 行 执<br />
CPU 序 的 其 他 部 分 在 程 言<br />
<strong>CUDA</strong> 编<br />
7<br />
第 4<br />
用 <strong>CUDA</strong><br />
设 宿 主 和 设 备 均 维 护 自 己 的 DRAM, 假<br />
2.0 南 , 版 本 指 程
及 (API)<br />
(software 包 stack)<br />
2-3. 异 图<br />
所<br />
和<br />
(device 应 这<br />
driver)、<br />
2.4 软 件 栈<br />
行 代 码 在 宿 主 上 执 行 , 而 并 行 代 码 在 设 备 上 执 行 。 串<br />
<strong>CUDA</strong> 软<br />
程<br />
: 设 备 驱 动 程 序 示<br />
件 栈<br />
含 多 个 层 , 如<br />
程 序 编 两 个 数 学 库 会 在 其 用<br />
程 异 构 编 8 <strong>CUDA</strong> 编<br />
CUBLAS,<br />
图 2-4<br />
文 档 中 介 绍 。 他<br />
程 接 口<br />
CUFFT 行 时 、 两 个 较 高 级 别 的 通 用 数 学 库 , 即 运 其<br />
2.0 南 , 版 本 指 程
提<br />
(compute 由 capability)<br />
。<br />
程 指 南 , 版<br />
软 件 栈<br />
中<br />
。<br />
。<br />
的<br />
设 备 ( 其<br />
<strong>CUDA</strong> 软<br />
2.5 计 算 能 力<br />
一 个 设 备 的 计 算 能 力<br />
图 2-4.<br />
主 要 修 订 号 和 次 要 修 订 号 定 义<br />
为 1)。 次 要 修 订 号 对 应 于 核 心 架 构 的 增 量 式 改 进 , 可 能 包 含 新 特 性 主<br />
A 录 附<br />
供 了 各 种 计 算 能 力 的 技 术 规 范<br />
A 相 同 主 要 修 订 号 的 设 备 属 于 相 同 的 核 心 架 构 。 附 录 有 具<br />
1.x 的 设 备 均 为 计 算 能 力 是 举 列<br />
<strong>CUDA</strong> 编<br />
9<br />
本 2.0
于<br />
年<br />
编 的<br />
个<br />
月<br />
function unit)、 一<br />
块<br />
块<br />
块<br />
节<br />
。Warp<br />
向 块<br />
,SIMT<br />
统<br />
,Tesla 架<br />
架<br />
(Scalar SP) Processor, 核<br />
向<br />
与<br />
块<br />
块<br />
块<br />
(on-chip)<br />
单<br />
允 宽<br />
,SIMT<br />
线<br />
在<br />
块<br />
个<br />
使<br />
语<br />
(transcendental)<br />
不<br />
(SIMD 而 行<br />
width),<br />
栅<br />
单<br />
,warp<br />
指<br />
块<br />
(cache<br />
第 3 章 GPU 实 现<br />
<strong>NVIDIA</strong><br />
GPU 和<br />
Tesla 架<br />
的 与<br />
计<br />
在 语<br />
GPU(<br />
GTX 280<br />
于 图 形 领 中 再 限 局<br />
核<br />
2006<br />
11<br />
Tesla 的 入 引<br />
图 形 和 计 算 架 构 扩 展 了 GPU, 一<br />
GPU<br />
3.1 具 有 片 上 共 享 存 储 器 的 一 组 SIMT 多 处 理 器<br />
, 其 强 大 的 多 线 程 处 理 器 阵 列 已 经 成 为 高 效 的 统 一 平 台 —— 同 时 适 用 于 图 形 和 通 用 并 行 计 算 应 用 程 序 。 域<br />
件 , 使 这 种 架 构 成 为 最 优 秀 的 超 级 计 算 平 台 。 软<br />
通 过 扩 展 处 理 器 和 存 储 器 的 数 量<br />
GeForce 盖 了 市 场 上 全 线 产 品 , 从 高 性 能 发 烧 级 覆 构<br />
Quadr 业 专<br />
Tesla<br />
GeForce 品 , 一 直 到 多 种 主 流 经 济 型 产 算<br />
A 录 附<br />
可 查 看 所 有<br />
<strong>CUDA</strong> 持 支<br />
GPU<br />
<strong>CUDA</strong> )。 其 计 算 特 性 支 持 利 用 表 列<br />
C<br />
GPU 直 观 地 编 写 中 言<br />
心 程 序 。<br />
Tesla<br />
上 架<br />
程<br />
(Streaming SM) Multiprocessors, 阵<br />
C 有 在 笔 记 本 电 脑 、 台 式 机 、 工 作 站 和 服 务 器 上 的 广 泛 可 用 性 , 配 以 具 构<br />
<strong>CUDA</strong> 程 能 力 和 编 言<br />
的 构 建 以 一 个 可 伸 缩 的 多 线 程 流 式 多 处 理 器 列 为 中 心 。 当 宿 序 调 用 内 核 网 格 时 , 网 格 的 块 将 被 枚 举 并 分 发 到 具 有 可 用 执 行 能 力 的 多 处 理 器 上 。 构<br />
8<br />
(special<br />
器 包 含 功 能 单 元 理 处 多<br />
标 量 处 理 器<br />
、 两 个 用 于 超 越 函 数 特 殊 个 多 线 程 指 令 单 元 以 及 片 上 享 存 储 器 。 多 处 理 器 会 在 硬 心<br />
个 线 程 块 的 线 程 在 一 个 多 处 理 器 上 并 发 执 行 。 在 线 程 块 终 止 时 , 将 在 空 闲 多 处 理 器 上 启 动 新 块 。 的 一<br />
<strong>CUDA</strong> 章 介 绍 一 这<br />
Tesla 型 与 模 程<br />
的 对 应 关 系 。 构<br />
共<br />
multiple-thread, 单<br />
warp 块<br />
步 。 快 速 的 栅 障 同 步 与 轻 量 级 线 程 创 建 和 零 开 销 的 线 程 调 度 相 结 合 , 有 效 地 为 细 粒 度 并 行 化 提 供 了 支 持 , 举 例 来 说 , 您 可 以 为 各 数 据 元 素 ( 如 图 像 中 的 一 个 像 素 、 语 音 中 的 一 个 语 音 元 素 、 基 于 网 格 的 计 算 中 的 一 同<br />
主 CPU<br />
的 <strong>CUDA</strong><br />
个 单 元 ) 分 配 一 个 线 程 , 从 而 对 问 题 进 行 细 粒 度 分 解 。<br />
令 、 多 线 程 ) 的 新 架 构 。 多 处 理 器 会 将 各 线 程 映 射 到 一 个 标 量 处 理 器 核 心 , 各 标 量 线 半 指<br />
可 随 意 分 支 、 独 立 执 行 。 都 包 含 连 续 的 线 程 , 递 增 线 也<br />
包 含 线 程 0。 中<br />
中 的 线 程 索 引 之 间 的 关 系 。 块<br />
次 准 备 发 出 一 条 指 令 时 的 活 动 线 程 每<br />
并 将 待 发 出 的 指 令 发 送 到 该 的 全 线 程 均 有 明 确 的 执 行 ,<br />
中 创 建 、 管 理 和 执 行 并 发 线 程 , 而 调 度 开 销 保 持 为 0。 它 可 通 过 一 条 内 部 指 令 实 件<br />
现 __syncthreads()<br />
障<br />
warp 块<br />
块 单<br />
块<br />
块 块<br />
个<br />
块<br />
SIMT(single-instruction, 管 理 运 行 各 种 不 同 程 序 的 数 百 个 线 程 , 多 处 理 器 利 用 了 一 种 称 为 了 为<br />
路 径 时 , 可 达 到 最 高 效 率 。 如 果 一<br />
的 线 程 通 过 独 立 于 数 据 的 条 件 分 支 而 分 散<br />
将 连 续<br />
第<br />
warp 调 度 和 执 行 线 程 , 这 样 的 线 程 组 称 为 、 理<br />
此 术 语 源 于 第 一 种 并 行 线 程 技 术 weaving。 。(<br />
warp<br />
程 使 用 自 己 的 指 令 地 址 和 寄 存 器 状 态 独 立 执 行 。 多 处 理 器 SIMT<br />
32 以 元<br />
并 行 线 程 为 一 组 来 创 建 、 管<br />
warp 是 一 个 以 可<br />
SIMT 一 半 或 第 二 半 。) 构 成 第 的<br />
的 各 个 线 程 在 同 一 个 程 序 地 址 一 起 启 动 , 但<br />
执 行 所 使 用 的 各 分 支 路 径 , 而 禁 用 未 在 此 路 径 上 的 线 程 , 完 成 所 有 路 径 时 , 线 程 重 新 汇 聚 到 同 一 执 行 路 径<br />
warp 个 多 处 理 器 指 定 了 一 个 或 多 个 要 执 行 的 线 程 块 时 , 它 会 将 其 分 成 一 为<br />
SIMT 由 并 ,<br />
元 进 行 调 度 。<br />
10 <strong>CUDA</strong> 编<br />
warp 分 割 为 块 将<br />
warp 法 总 是 相 同 的 , 每 个 方 的<br />
程 ID,<br />
warp 个 一<br />
SIMT 架<br />
第 2.1<br />
ID 了 线 程 绍 介<br />
warp 会 选 择 一 个 可 待 使 用 的 都 元<br />
warp 执 行 一 条 通 用 指 令 , 因 此 在 次 每<br />
部 32<br />
线<br />
个 warp<br />
彼 此 无 关 的 代 码 路 径 。 单 是<br />
warp 分 支 仅 在 。 下<br />
warp 现 , 不 同 的 出 内<br />
总 是 独 立 执 行 的 —— 无 论 它 们 执 行 的 是 通 用 的 代 码 路 径 还<br />
类 似 于 SIMD( 构<br />
指 令 、 多 数 据 ) 向 量 组 织 方 法 , 共 同 之 处 是 使 用 单 指 令 来 控 制 多 个 处 理 元 素 。<br />
warp 个 一 少<br />
cache 线 程 分 支 , 即 可 实 现 显 著 的 性 能 提 升 。 在 实 践 中 , 这 与 传 统 代 码 中 的 的 内<br />
2.0 南 , 版 本 指 程<br />
SIMD 主 要 差 别 在 于 项 一<br />
SIMD 织 方 法 会 向 软 件 公 开 组 量<br />
度<br />
SIMT<br />
令 指 定 单<br />
SIMT , 还 允 许 为 协 同 线 程 编 写 数 据 并 行 代 码 。 为 了 确 保 正 确 性 , 程 序 员 可 忽 略 码 代<br />
为 , 但 通 过 尽 量 减<br />
作 计 , 在 代 码 结 构 中 就 必 须 考 虑 其 大 小 。 另 一 方 面 , 向 量 架 构 要 求 软 件 操 作 存 储 器 合 并 , 并 手 动 管 理 分 支 。<br />
line)<br />
SIMD 程 的 执 行 和 分 支 行 为 。 与 线 一<br />
量 机 不 同<br />
许 程 序 员 为 独 立 、 标 量 线 程 编 写 线 程 级 的 并 行<br />
cache 似 : 在 以 正 确 性 为 目 标 进 行 设 计 时 , 可 忽 略 相 用<br />
的 大 小 , 但 如 果 以 峰 值 性 能 为 目 标 进 行 设
所<br />
块<br />
位<br />
(constant<br />
(texture<br />
(texture<br />
cache), 由<br />
cache), 由<br />
写 访 unit)<br />
程 指 南 , 版<br />
块<br />
一 项 读 取 、 修 改 或 写 入 操 作 都 将 发 生 , 且 均 为 串 行 化 操 作 , 但 这 些 操 作 所 发 生 的 顺 序 无 法 确 定 。 块<br />
多<br />
硬<br />
节<br />
个<br />
<br />
<br />
<br />
并 每<br />
行 数 据 缓 存 或 共 享 存 储 器 , 由 所 有 标 量 处 理 器 核 心 共 享 , 共 享 存 储 器 空 间 就 位 于 此 处<br />
<br />
3-1 图 如<br />
个 只 读 纹 理 缓 所 有 标 量 处 理 器 核 心 共 享 , 加 速 从 纹 理 存 储 器 空 间 进 行 的 读 取 操 作 ( 这 是 设 备 存 储 器 的 一 个 只 读 区 域 ), 每 个 多 处 理 器 都 会 通 过 实 现 不 同 寻 址 模 型 和 数 据 过 滤 的 纹 一<br />
作 ( 这 是 设 备 存 储 器 的 一 个 只 读 区 域 );<br />
32 理 器 上 有 一 组 本 地 处 个<br />
存 器 ; 寄<br />
, 每 个 多 处 理 器 都 有 一 个 属 于 以 下 四 种 类 型 之 一 的 片 上 存 储 器 : ; 只 读 常 量 缓 存 所 有 标 量 处 理 器 核 心 共 享 , 可 加 速 从 常 量 存 储 器 空 间 进 行 的 读 取 操 示<br />
个 多 处 理 器 一 次 可 处 理 的 块 数 量 取 决 于 给 定 的 内 核 中 , 每 个 线 程 需 要 多 少 个 寄 存 器 、 每 个 块 需 要 多 少 共 享 存 储 器 , 这 是 因 为 多 处 理 器 的 寄 存 器 和 共 享 存 储 器 被 分 配 给 一 批 块 的 所 有 线 程 。 如 果 没 有 足 够 的 寄 存 器 线 程 块 。 一<br />
理 单 元<br />
4.3.4 理 缓 存 , 相 关 内 容 请 参 见 第 纹 问<br />
。<br />
8 享 存 储 器 可 供 多 处 理 器 用 于 处 理 至 少 一 个 块 , 内 核 会 无 法 启 动 。 一 个 多 处 理 器 可 并 发 执 行 最 多 共 或<br />
/ 和 全 局 存 储 器 空 间 是 设 备 存 储 器 的 读 区 域 , 无 缓 存 。 地 本<br />
warp 行 原 子 指 令 来 为 执 块<br />
的 多 个 线 程 读 取 、 修 改 和 写 入 全 局 存 储 器 中 的 同 一 位 置 , 则 针 对 该 位 置 的 每<br />
warp 果 如<br />
warp 的 非 原 子 指 令 为 行 执<br />
的 多 个 线 程 写 入 全 局 或 共 享 存 储 器 中 的 同 一 位 置 , 针 对 此 位 置<br />
warp 行 化 写 入 操 作 的 数 量 和 这 些 写 入 操 作 所 发 生 的 顺 序 将 无 法 确 定 , 但 其 中 一 项 操 作 必 将 成 功 。 如 果 串 的<br />
具 有 片 上 共 享 存 储 器 的 一<br />
理 器 处<br />
<strong>CUDA</strong> 编<br />
11<br />
硬 件 模 型<br />
本 2.0<br />
组 SIMT<br />
图 3-1.
模<br />
系<br />
位<br />
键<br />
而 导 致 此 类 应 用 程 序 崩 溃 。 从<br />
模<br />
能<br />
应<br />
作<br />
可 视 设<br />
设<br />
(primary 它 控 的<br />
surface),<br />
键<br />
上 应 MB。(<br />
应<br />
必<br />
的<br />
都<br />
3.2 多 个 设 备<br />
备 , 因 为 所<br />
须 具 有 相<br />
3.3 模 式 切 换<br />
SLI 类 型 。 但 如 果 系 统 采 用 的 是 内 关 式 。 的 同<br />
, 则 仅 有 一 够 将 式<br />
GPU 在 多 要 若<br />
GPU 运 行 , 且 应 用 程 序 将 多 个 上 统<br />
GPU 将<br />
存<br />
储 器 专 门 用 于 处 理 所 谓 的 主 表 面<br />
为 <strong>CUDA</strong><br />
GPU 用 , 则 这 些 使 备<br />
用 于 刷 新 用 户 所 见 的 显 示 设<br />
个 GPU<br />
<strong>CUDA</strong> 作 用<br />
MB 的<br />
控 制 面 板 将<br />
示 控 制 面 板 ) 发 显<br />
有 GPU<br />
<strong>CUDA</strong> 动 程 序 栈 的 最 低 级 别 融 合 。 要 使 驱 在<br />
各 GPU<br />
<strong>CUDA</strong> 立 设 备 , 需 要 在 独 为<br />
闭 SLI<br />
DRAM 分 部<br />
<strong>NVIDIA</strong> 当 用 户 通 过 更 改 显 示 器 的 分 辨 率 或 位 深 度 ( 使 用 。 备<br />
Windows 板 或 面 制<br />
1280x1024x32 式 切 换 时 , 主 表 面 所 需 的 存 储 器 数 量 会 随 之 改 变 。 例 如 , 如 果 用 户 将 显 示 器 的 分 辨 率 从 模 起<br />
1600x1200x32 改 为 更 位<br />
7.68 统 必 须 为 主 表 面 分 配 系 ,<br />
5.24 器 , 而 不 是 储 存<br />
使 用 防 锯 齿<br />
Windows 运 行 的 全 屏 图 形 应 用 程 序 可 能 需 要 为 主 表 面 分 配 更 多 显 示 存 储 器 。) 在 置 设<br />
, 其 他 事 件 也 可 能<br />
<strong>CUDA</strong> 模 式 切 换 增 加 了 主 表 面 所 需 的 存 储 器 数 量 , 系 统 可 能 就 必 须 挪 用 分 配 给 果 如<br />
用 程 序 的 存 储 器 ,<br />
会 启 动 显 示 模 式 切 换 , 包 括 启 动 全 屏 DirectX<br />
Alt+Tab 序 、 按 程 用<br />
DirectX 屏 全 从<br />
用 程 序 中 切 换<br />
Ctrl+Alt+Del 或 者 按 来 出<br />
定 计 算 机 。 锁<br />
12 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
编<br />
的<br />
,C 标<br />
限<br />
(host)<br />
(function<br />
(variable qualifier), type<br />
编 指<br />
。<br />
进<br />
,4.2.5 节<br />
节<br />
,nvcc 发 出 错 误 或 警 报 将<br />
第 4 章 应 用 程 序 编 程 接 口<br />
4.1 C 编 程 语 言 的 扩 展<br />
<strong>CUDA</strong> 编<br />
编<br />
序 。 它 包 含 : 节 程<br />
运 行 时 库 , 可 分 割 为 : 个<br />
C<br />
<br />
<br />
一 语<br />
节<br />
<br />
<br />
一<br />
组<br />
节 标<br />
C 口 的 目 标 是 为 熟 悉 接 程<br />
程 语 言 的 用 户 提 供 相 对 简 单 的 途 径 , 使 之 可 轻 松 编 写 由 设 备 执 行 的<br />
4.2 最 小 扩 展 集 , 如 的 言<br />
述 , 这 允 许 程 序 员 使 源 代 码 的 某 些 部 分 可 在 设 备 上 执 行 ; 所<br />
有 必 要 强 调<br />
库 中 支 持 在 设 备 上 运 行 的 函 数 只 有 通 用 运 行 时 组 件 所 提 供 的 函 数 。 准<br />
4.2 语 言 扩 展<br />
。 集 子 此 持 支 将<br />
语 言 扩 展<br />
个 计 算 设 备 ; 多<br />
一 个 宿 主<br />
4.5 如 , 件<br />
所 述 , 运 行 在 宿 主 上 , 提 供 函 数 来 通 过 宿 主 控 制 和 访 问 一 个 或<br />
4.4 备 组 件 , 如 设 个<br />
述 , 运 行 在 设 备 上 , 提 供 特 定 于 设 备 的 函 数 ; 所<br />
<br />
qualifier), type<br />
节 指<br />
4.3 通 用 组 件 , 如 个 一<br />
C , 提 供 内 置 向 量 类 型 和 述 所<br />
准 库 的 一 个 子 集 , 宿 主 和 设 备 代 码 都<br />
4.2.1<br />
类 型 限 定 符 宿 主 还 是 可 通 过 设 备 调 用 ( 参 见 第 数 函<br />
函 数 是 在 宿 主 上 还 是 设 备 上 执 行 , 以 及 函 数 是 可 通 过 ); 定<br />
语 言 的 扩 展 共 有 四 重 : 程<br />
<br />
<br />
四 一 变<br />
节 节<br />
条 新 指 令 , 指 定 如 何 通 过 宿 主 在 设 备 上 执 行 内 核 ( 参 见<br />
对 C<br />
);<br />
)。<br />
);<br />
量 类 型 限 定 符<br />
4.2.2 个 变 量 在 设 备 上 的 存 储 器 位 置 ( 参 见 第 一 定<br />
简 单 介 绍 了 相 关 内 容 。 关<br />
4.2.3<br />
编 介 将 其 文 中 供 第<br />
4.2.1 函 数 类 型 限 定 符<br />
一 些 限 制 , 下 面 几 个 小 节 将 分 别 加 以 介 绍 。 如 果 违 背 了 这 些 限 制 信 息 , 但 有 些 违 规 情 况 无 法 检 测 到 。 有 具 均 展 扩 些 。 提 档 他 在 绍 体 译 行 这<br />
函 数 类 型 限 定 符<br />
4.2.4 置 变 量 , 指 定 网 格 和 块 维 度 以 及 块 和 线 程 索 引 ( 参 见 第 内 个<br />
<strong>CUDA</strong> 这 些 扩 展 的 所 有 源 文 件 都 必 须 使 用 含 包<br />
nvcc 器 译<br />
4.2.1.1 __device__<br />
于 nvcc<br />
<br />
仅 在<br />
<strong>CUDA</strong><br />
设 备 上 执 行 ; 可 通 过 设 备 调 用<br />
编<br />
定 符 声 明 的 函 数 具 有 以 下 特 征 :<br />
13<br />
__device__ 用 使<br />
2.0 南 , 版 本 指 程
限<br />
限<br />
限<br />
限<br />
和<br />
限<br />
(void)。<br />
:<br />
限 定 符 声 明 函 数 , 。 或<br />
variable)。<br />
(static<br />
字<br />
。<br />
限<br />
。<br />
4.2.1.2 __global__<br />
<br />
仅 在<br />
定 符 可 将 函 数 声 明 为 内 核 。 此 类 函 数<br />
4.2.1.3 __host__<br />
。<br />
<br />
仅 在<br />
备 上 执 行 ; 可 通 过 宿 主 调 用 设<br />
主 上 执 行 ; 宿<br />
__global__ 用 使<br />
通 过 宿 主 调 用 。 定 符 声 明 函 数 等 同 于 不 使 可<br />
4.2.1.4 限 制<br />
__host__ 用 使<br />
符 声 明 的 函 数 具 有 以 下 特 征 : 定<br />
使<br />
__device__<br />
仅<br />
和 __device__<br />
__device__<br />
__device__<br />
__global__<br />
__global__ 函 和 函 限<br />
。 函<br />
节<br />
用 __host__<br />
用 __host__、__device__<br />
__global__<br />
这 两 种 情 况 下 , 函 数 都 将 仅 为 宿 主 进 行 编 译 。<br />
但 __host__<br />
定 符 一 起 使 用 , 此 时 函 数 将 为 宿 主 和 设 备 进 行 编 译<br />
__device__ 也 可 与 符 定<br />
不 支 持 递 归 。<br />
函 体 内 无 法 声 明 静 态 变 量 数 的 参 数 不 得 为 变 量 。<br />
__global__<br />
__global__ 函 函<br />
__global__ 函<br />
__global__<br />
__global__<br />
符 无 法 一 起 使 用<br />
4.2.2 变 量 类 型 限 定 符<br />
变 量 类 型 限 定 符<br />
__global__ 地 址 无 法 获 取 , 但 支 持 的 数<br />
__host__<br />
的 函 数 指 针 。 介 绍 的 方 法 指 定 其 执 行 配 置 数<br />
4.2.2.1 __device__<br />
数 的 返 回 类 型 必 须 为 空<br />
的 调 用 是 异 步 的 , 也 就 是 说 它 会 在 设 备 执 行 完 成 之 前 返 回<br />
__device__<br />
数<br />
限<br />
<br />
<br />
可 与 位<br />
符 声 明 位 于 设 备 上 的 变 量 。 体 地 指 定 变 量 属 于 哪 个 存 储 器 空 间 。 如 果 未 出 现 其 他 任 何 限 定 符 , 则 变 量 具 有 以 下 特 征 : 定<br />
全 局 存 储 器 空 间 中 ; 应 用 程 序 具 有 相 同 的 生 命 周 期 ; 于<br />
对 __global__<br />
4.2.3 任 何 调 用 都 必 须 按 第 的 数<br />
定 符 一 起 使 用 , 以 更 具<br />
256 数 将 同 时 通 过 共 享 存 储 器 传 递 给 设 备 , 且 限 制 为 参 数<br />
。 节<br />
4.2.2.2 __constant__<br />
__constant__ 限<br />
限<br />
<br />
与 位<br />
过 网 格 内 的 所 有 线 程 访 问 , 也 可 通 过 运 行 时 库 从 宿 主 访 问 。 通<br />
常 量 存 储 器 空 间 中 ; 应 用 程 序 具 有 相 同 的 生 命 周 期 ; 于<br />
14 <strong>CUDA</strong> 编<br />
__device__ 下 来 的 三 节 中 介 绍 的 其 他 类 型 限 定 符 中 , 最 多 只 能 有 一 种 可 与 接 在<br />
__device__ 可 选 择 与 符 定<br />
符 一 起 使 用 , 所 声 明 的 变 量 具 有 以 下 特 征 : 定<br />
2.0 南 , 版 本 指 程
节<br />
变<br />
和<br />
助<br />
变<br />
(implied<br />
(segmentation 和 fault)<br />
助<br />
节<br />
可<br />
4.2.2.3 __shared__<br />
__shared__ 限<br />
<br />
<br />
尽 与 位<br />
过 网 格 内 的 所 有 线 程 访 问 , 也 可 通 过 运 行 时 库 从 宿 主 访 问 。 通<br />
于 线 程 块 的 共 享 存 储 器 空 间 中 ; 限<br />
具 有 相 同 的 生 命 周 期 ; 节 块<br />
extern __shared__ float shared[];<br />
节<br />
short array0[128];<br />
float array1[64];<br />
int array2[256];<br />
通 过 块 内 的 所 有 线 程 访 问 。 参 将 共 享 存 储 器 声 明 为 外 部 数 组 时 , 例 如 : 可<br />
, 因 此 数 组 中 的 变 量 布 局 必 须 通 过 偏 移 显 式 管 理 。 例 如 , 如 果 一 名 用 户 希 望 在 动 态 分 配 的 共 享 存 储 器 内 始<br />
__device__ 可 选 择 与 符 定<br />
符 一 起 使 用 , 所 声 明 的 变 量 具 有 以 下 特 征 : 定<br />
extern __shared__ char array[];<br />
__device__ void func() // __device__ or __global__ function<br />
{<br />
short* array0 = (short*)array;<br />
float* array1 = (float*)&array0[128];<br />
int* array2 = (int*)&array1[64];<br />
}<br />
得 与 以 下 代 码 对 应 的 内 容 : 则 应 通 过 以 下 方 法 声 明 和 初 始 化 数 组 : 获<br />
有 在 __syncthreads()( 只<br />
4.4.2 第 见<br />
) 的 执 行 写 入 之 后 , 才 能 保 证 共 享 变 量 对 其 他 线 程 可 见 。 除 非 变<br />
volatile 声 明 为 被 量<br />
, 否 则 只 要 之 前 的 语 句 完 成 , 编 译 器 即 可 随 意 优 化 共 享 存 储 器 的 读 写 操 作 。 量<br />
4.2.3 的 大 小 将 在 启 动 时 确 定 ( 参 见 第 组 数<br />
)。 所 有 变 量 均 以 这 种 形 式 声 明 , 在 存 储 器 中 的 同 一 地 址 开<br />
4.2.2.4 限 制<br />
和<br />
成<br />
__shared__ 和<br />
变<br />
static storage)。<br />
__constant__<br />
量 无 法 使<br />
字 定 义 为 外 部 变 量 。 键<br />
__device__、__shared__ 和<br />
变<br />
关<br />
__device__ 和<br />
变<br />
struct 限 定 符 不 允 许 被 用 于 在 宿 主 上 执 行 的 函 数 内 的 些 这<br />
union<br />
的 形 参 和 局 部 变 量 。 员<br />
_shared_ 变<br />
量 的 声 明 中 不 可 包 含 初 始 化<br />
和<br />
)。<br />
__constant__<br />
量 具 有 隐 含 的 静 态 存 储<br />
设 备 代 码 中 声 明 、 不 带 任 何 限 定 符 的 自 动 变 量 通 常 位 于 寄 存 器 中 。 但 在 某 些 情 况 下 , 编 译 器 可 能 择 将 其 置 于 本 地 存 储 器 中 。 如 果 使 用 占 用 了 过 多 寄 存 器 空 间 的 大 型 结 构 或 数 组 , 或 者 编 译 器 无 法 确 定 其 是 否 使 汇 或 选 在<br />
options =-v<br />
。<br />
选<br />
用 extern<br />
__constant__<br />
仅 允 许 在 文 件 作 用 域 内 使 用 。 量<br />
<strong>CUDA</strong> 编<br />
针 即 受 支 持 , 否 则 将 仅 限 于 指 向 在 全 局 存 储 器 空 间 中 分 配 或 声 明 的 存 储 器 。<br />
15<br />
__constant__ 为 设 备 或 从 设 备 指 派 可 不<br />
4.5.2.3 仅 可 通 过 宿 主 运 行 时 函 数 从 宿 主 指 派 ( 参 见 第 , 量<br />
第 4.5.3.6<br />
--ptxas- 寄 存 器 空 间 。 可 通 过 使 用 多 过<br />
项 编 译 来 进 行 检 查 , 这 将 报 告 本 地 存 储 器 的 使 用 情 况<br />
ptx 定 数 量 索 引 的 数 组 , 则 往 往 会 出 现 这 种 情 况 。 检 查 固 用<br />
–ptx 码 ( 通 过 使 用 代 编<br />
–keep<br />
项 编<br />
用 , 将 导 致 不 确 定 的 行 为 , 往 往 会 出 现 分 区 错 误<br />
用 程 序 终 止 。 应<br />
.local 得 ) 即 可 在 初 次 编 译 过 程 中 确 定 一 个 变 量 是 否 位 于 本 地 存 储 器 中 , 因 为 它 将 使 用 获 译<br />
记 符 声 明 ,<br />
如 果 取 消 在 宿 主 上 执 行 的 代 码 中 全 局 或 共 享 存 储 器 指 针 , 或 者 在 设 备 上 执 行 的 代 码 中 宿 主 存 储 器 指 针 的 引<br />
只 要 编 译 器 能 够 确 定 在 设 备 上 执 行 的 代 码 中 的 指 针 指 向 的 是 共 享 存 储 器 空 间 还 是 全 局 存 储 器 空 间 , 此 类 指<br />
(lmem)。<br />
ld.local 用 使 可<br />
st.local<br />
记 符 访 问 。 如 果 不 是 这 样 , 在 后 续 编 译 阶 段 仍 能 确 定 是 否 占 用 了 目 标 架 构 的<br />
2.0 南 , 版 本 指 程
函<br />
或<br />
节<br />
节<br />
节<br />
节<br />
节 变<br />
;S<br />
变 或<br />
configuration)。<br />
(execution<br />
或<br />
,Dg.x<br />
,Db.x<br />
节<br />
是<br />
(<br />
4.2.3 执 行 配 置<br />
主 代 码 中 使 用 。 宿<br />
取 __device__、__shared__<br />
通 过 获<br />
__constant__<br />
量 的 地 址 而 获 得 的 地 址 仅 可 在 设 备 代 码 中 使 用 。 通<br />
Dg<br />
Dg.z<br />
Db 的 无 节<br />
节<br />
Db, Ns, s>>> 形<br />
* Dg.y 等<br />
* Db.y * Db.z 等<br />
量 的 地 址 仅 可 在<br />
过 cudaGetSymbolAddress()<br />
4.5.23 第 见 参<br />
__device__ 取 的 获 )<br />
__constant__<br />
对 __global__<br />
<br />
Ns 的<br />
4.5.1.5 配 置 定 义 将 用 于 在 该 设 备 上 执 行 函 数 的 网 格 和 块 的 维 度 , 以 及 相 关 的 流 ( 有 关 流 的 内 容 将 在 第 行 执<br />
工<br />
代<br />
语<br />
,__device__ 函<br />
对<br />
块<br />
驱<br />
源<br />
小 。 大<br />
代<br />
在<br />
所<br />
(inlined)。__noinline__ 函<br />
(trip<br />
。#pragma<br />
语<br />
限<br />
节 对<br />
对<br />
4.2.4.5 warpSize<br />
4.2.4.6 限 制<br />
<br />
不 4.2.5 使 用 NVCC 进 行 编 译<br />
包 试 图 获 取 任 何 内 置 变 量 的 地 址 。 允 许 为 任 何 内 置 变 量 赋 值 。<br />
变 量 的 类 型 为 int, 此<br />
warp 线 程 为 单 位 的 以 含<br />
nvcc 是<br />
nvcc 的<br />
<strong>CUDA</strong> 可 简 化 种 一<br />
编 译 过 程 的 编 译 器 驱 动 程 序 : 它 提 供 了 简 单 、 熟 悉 的 命 令 行 选 项 , 通 过 调 用 实 现 不 同 编 译 阶 段 的 工 具 集 合 来 执 行 它 们 。 基 本 工 作 流 在 于 将 设 备 代 码 与 宿 主 代 码 分 离 开 来 , 并 将 设 备 代 码 编 译 为 二 进 制 形 式 象 。 码<br />
或 cubin<br />
4.5.2 节<br />
运<br />
的<br />
子<br />
特<br />
语<br />
C 成 的 宿 主 代 码 将 作 为 需 要 使 用 其 他 工 具 编 译 的 生 所<br />
码 输 出 , 或 通 过 在 最 后 一 个 编 译 阶 段 中 调 用 宿 主<br />
译 器 直 接 作 为 对 象 代 码 输 出 。 编<br />
)。<br />
<strong>CUDA</strong> 程 序 可 忽 略 所 生 成 的 宿 主 代 码 , 使 用 用 应<br />
API 序 程 动<br />
cubin 上 加 载 并 执 行 备 设<br />
象 , 也 可 链<br />
cubin 所 生 成 的 宿 主 代 码 , 其 中 包 含 到 接<br />
4.2.3 其 形 式 为 全 局 初 始 化 数 据 数 组 , 包 含 将 第 , 象<br />
所 述 执<br />
<strong>CUDA</strong> 置 语 法 转 换 为 必 要 的 配 行<br />
启 动 代 码 的 转 换 , 目 的 在 于 加 载 和 启 动 编 译 后 的 各 内 核 ( 参 见 第 行<br />
C++ 器 的 前 端 根 据 译 编<br />
<strong>CUDA</strong> 则 处 理 规 法<br />
C++ 。 宿 主 代 码 支 持 完 整 的 件 文<br />
法 。 但 设 备 代 码 仅 支<br />
nvcc 引<br />
4.2.5.1 __noinline__<br />
认 情 况 下 数 总 是 内 联 要 内 联 该 函 数 。 函 数 体 必 须 位 于 所 调 用 的 同 一 个 文 件 内 。 默<br />
数 限 定 符 可 用 于 指 示 编 译 器 尽 可 能 不<br />
持 C++<br />
C<br />
C++ 类 、 继 承 、 基 本 块 内 的 变 量 声 明 等 , 集<br />
C++ 性 不 受 支 持 。 由 于 使 用 了 特 殊<br />
法<br />
了 两 个 编 译 器 指 令 , 下 面 几 节 将 加 以 介 绍 。 入<br />
malloc() , 因 此 若 未 经 过 强 制 类 型 转 换 , 无 法 将 空 指 针 ( 例 如 则 规<br />
回 的 空 指 针 ) 指 派 给 非 空 指 针 。 返<br />
符 。 定<br />
nvcc 于 关<br />
流 和 命 令 选 项 的 详 细 说 明 将 在 其 他 文 档 中 提 供 。 作<br />
4.2.5.2 #pragma unroll<br />
认 情 况 下 , 编 译 器 将 展 开 具 有 已 知 行 程 计 数 小 循 环 令 可 用 于 控 制 任 何 给 定 循 环 的 展 开 操 作 。 它 必 须 紧 接 于 循 环 之 前 , 而 且 仅 应 用 于 该 循 环 。 可 选 择 在 其 后 接 一 个 数 字 , 指 定 默<br />
count) 的<br />
unroll 指<br />
#pragma unroll 5<br />
for (int i = 0; i < n; ++i)<br />
次<br />
小<br />
<strong>CUDA</strong> 编<br />
17<br />
__noinline__ 函 数 具 有 指 针 参 数 或 者 具 有 较 大 的 参 数 列 表 , 则 编 译 器 不 会 遵 从 果 如<br />
#pragma unroll 1 将<br />
unroll 后<br />
须 展 开 多 少 次 循 环 。 例 如 , 在 下 面 的 代 码 示 例 中 : 必<br />
则 程 序 的 正 确 性 将 受 到 影 响 )。 阻 止 编 译 器 展 开 一 个 循 环 。<br />
5,<br />
5 将 展 开 环 循<br />
n 序 员 需 要 负 责 确 保 展 开 操 作 不 会 影 响 程 序 的 正 确 性 ( 在 上 面 的 示 例 中 , 如 果 程 。<br />
于<br />
2.0 南 , 版 本 指 程<br />
#pragma 在 果 如<br />
未 指 定 任 何 数 据 , 如 果 其 行 程 计 数 为 常 数 , 则 该 循 环 将 完 全 展 开 , 否 则 将 不 会 展
的<br />
y)。<br />
的<br />
4.3 通 用 运 行 时 组 件<br />
4.3.1 内 置 向 量 类 型<br />
。 开<br />
4.3.1.1 char1、uchar1、char2、uchar2、char3、uchar3、char4、uchar4、<br />
short1、ushort1、short2、ushort2、short3、ushort3、short4、ushort4、<br />
int1、uint1、int2、uint2、int3、uint3、int4、uint4、long1、ulong1、long2、<br />
主 和 设 备 函 数 均 可 使 用 通 用 运 行 时 组 件 。 宿<br />
ulong2、long3、ulong3、long4、ulong4、float1、float2、float3、float4、<br />
double2<br />
y、z 和<br />
访<br />
int2 make_int2(int x, int y);<br />
name> 的<br />
个<br />
4.3.1.2 dim3 类 型<br />
1、2、3、4 向 量 类 型 继 承 自 基 本 整 形 和 浮 点 类 型 。 它 们 均 为 结 构 体 , 第 些 这<br />
量 分 别 可 通 过 字 段 x、 分<br />
w<br />
make_
、2 分<br />
位 是 的<br />
节<br />
(texture<br />
(texture reference) 的 的 fetch)<br />
“texture 纹 elements(<br />
类<br />
且<br />
。<br />
;Type 仅<br />
。<br />
或<br />
和<br />
位<br />
1.0], 有<br />
节<br />
和<br />
节<br />
(texture 将 coordinate)<br />
节<br />
1.0], 例<br />
和<br />
和<br />
,1.25<br />
“wrap”<br />
的<br />
寻 或<br />
。Wrap<br />
的<br />
的<br />
间<br />
节<br />
第<br />
的 围<br />
。 对 于<br />
4.3.4 纹 理 类 型<br />
<strong>CUDA</strong> 支<br />
用<br />
数 据 可 带 来 多 方 面 的 性 能 收 益 , 请 参 见 第 5.4<br />
个 参 数 指 定 称 为 纹 理 参 考<br />
对 象<br />
持 GPU<br />
于 图 形 的 纹 理 硬 件 子 集 , 使 之 可 访 问 纹 理 存 储 器 。 从 纹 理 存 储 器 而 非 全 局 存 储 器 读 取<br />
4.3.4.1 纹 理 参 考 声 明<br />
绑 定 到 存 储 器 的 某 些 区 域 ( 即 纹 理 ), 之 后 才 能 供 内 核 。 多 不 同 的 纹 理 参 考 可 绑 定 到 同 一 个 , 也 可 绑 定 到 在 存 储 器 中 存 在 重 叠 的 纹 理 。 纹 理 参 考 有 一 些 属 性 。 其 中 之 一 就 是 其 维 度 , 指 定 纹 理 是 使 用 一 个 纹 理 坐 标 纹 理 作 为 一 维 数 组 寻 址 、 使 用 两 个 纹 理 坐 标 作 为 二 维 数 组 寻 址 , 还 是 使 用 三 个 纹 理 坐 标 作 为 三 维 数 组 寻 址 。 数 组 其<br />
即<br />
内 核 使 用 称 为 纹 理 拾 取<br />
4.4.3 函 数 读 取 纹 理 存 储 器 , 请 参 见 第 备 设<br />
。 纹 理 拾 取 的 第 一<br />
4.5.2.6 参 考 定 义 拾 取 哪 部 分 的 纹 理 存 储 器 。 必 须 通 过 宿 主 运 行 时 函 数 ( 参 见 第 理 纹<br />
第 4.5.3.9<br />
) 将<br />
他 属 性 定 义 纹 理 拾 取 的 输 入 和 输 出 数 据 类 型 , 并 指 定 如 何 介 绍 输 入 坐 标 、 应 进 行 怎 样 的 处 理 。 其<br />
texture texRef;<br />
<br />
Type 指<br />
元 素 称 为 texel, 的<br />
元 素 )” 的 简 写 。 理<br />
1 的 义<br />
量<br />
量 和 4<br />
向 量 类 型 ; 量<br />
Dim<br />
ReadMode 等 指 分<br />
分<br />
或<br />
是<br />
为<br />
位<br />
理 参 考 的 部 分 属 性 是 不 变 的 , 在 编 译 时 必 须 为 已 知 , 这 些 属 性 是 在 声 明 纹 理 参 考 时 指 定 的 。 纹 理 参 考 在 其 中 : 纹<br />
texture 作 用 域 内 声 明 , 形 式 为 件 文<br />
的 变 量 : 型<br />
定 拾 取 纹 理 时 所 返 回 的 数 据 类 型<br />
4.3.1.1 基 本 整 型 、 单 精 度 浮 点 类 型 和 第 于 限<br />
定<br />
转 换 操 作 ;ReadMode<br />
如<br />
4.3.4.2 运 行 时 纹 理 参 考 属 性<br />
1、2 理 参 考 的 维 度 , 其 值 为 纹 定<br />
3;Dim<br />
个 可 选 的 参 数 , 默 认 值 为 1; 一<br />
于 cudaReadModeNormalizedFloat<br />
cudaReadModeElementType;<br />
果 是<br />
cudaReadModeNormalizedFloat,<br />
Type<br />
16<br />
或 8<br />
整 型 类 型 , 则 值 将 作 为 浮 点 类 型 返 回 , 对<br />
则<br />
于 所 有 整 型 数 据 而 言 , 无 符 号 整 型 将 映 射 为 [0.0,<br />
[-1.0, 整 型 将 映 射 为 号 符<br />
如 , 一 个<br />
0xff 为 值<br />
8 号 符 无<br />
不 执 行 任 何<br />
4.5.3.9 介<br />
N) 范<br />
。 的 它<br />
维<br />
1.0) 的<br />
1)。 一<br />
维<br />
是<br />
N), 因<br />
63]<br />
了 运 行 绍 介<br />
31]<br />
在 对 应 于 坐 标 的 维 度 中 的 大 小 。 范 纹 理 纹<br />
围<br />
理 元 素 将 被 读 取 为 1; 如 果 纹<br />
是 cudaReadModeElementType,<br />
个 可 选 的 参 数 , 默 认 值 为 cudaReadModeElementType。 一<br />
在 归 一 化 的 坐 标 内 , 同 般 情 况 下 , 纹 理 坐 标 与 纹 理 大 小 无 关 , 规 范 化 的 纹 理 坐 标 通 此<br />
<strong>CUDA</strong><br />
(clamp):<br />
编<br />
19<br />
执 行 低 精 度 插 值 。 在 启 用 时 , 视<br />
理 参 考 的 其 他 属 性 是 可 变 的 , 可 通 过 宿 主 运 行 时 在 运 行 时 更 改 ( 们 指 定 纹 理 坐 标 是 否 为 归 一 化 的 滤 , 下 面 将 介 绍 相 关 内 容 围 内 的 浮 点 坐 标 引 用 纹 理 , 其 中 纹<br />
如 , 有 一 个 大 小 例<br />
N 的<br />
(normalized)<br />
第 4.5.2.6<br />
时 API,<br />
了 驱 动 程 序 API)。 绍<br />
, 以 及 寻 址 模 式 和 纹 理 过<br />
理 的 寻 址 范 围 在 x<br />
N) 范<br />
[0, 情 况 下 , 使 用 认 默<br />
1.0) 内<br />
使 用 归 一 化 在<br />
被 的<br />
被<br />
为 64x32<br />
x , 在 理 纹<br />
y<br />
[0, 用 此 纹 理 时 坐 标 分 别 处 于 引 度<br />
将 被 调 整 到 范 址 往 往 在 纹 理 包 含 周 期 信 号 时 使 用 。 它 仅 使 用 纹 理 值<br />
[0,<br />
[0.0, 归 一 化 的 纹 理 坐 标 将 在 。 内<br />
[0, 内 指 定 , 而 非 围 范<br />
一 64x32<br />
寻 址 模 式<br />
足 以 满 足 一 些 应 用 程 序 的 需 求 。 小 常<br />
y<br />
[0, 为 均 度<br />
围 [0.0,<br />
2.0 南 , 版 本 指 程<br />
[0, 模 式 定 义 在 纹 理 坐 标 超 出 范 围 时 将 出 现 怎 样 的 情 况 。 在 使 用 非 归 一 化 纹 理 坐 标 时 , 超 出 址 寻<br />
纹 理 坐 标 将 被 调 整<br />
于 0<br />
被 设 置 为 0, 大 于 或 等 值<br />
于 N<br />
被 设 置 为 N-1。 值<br />
0.0 坐 标 时 , 默 认 寻 址 模 式 也 是 调 整 坐 标 : 小 于 理 纹<br />
1.0 于 大<br />
为 0.75.<br />
一 化 坐 标 , 也 可 指 定 坐 标 的 一 部 分 , 例 如 归<br />
视<br />
为 0.25,-1.25<br />
texel 纹 理 过 滤 只 能 对 配 置 为 返 回 浮 点 数 据 的 纹 理 进 行 。 这 将 在 相 邻 性 线
提<br />
节<br />
前<br />
将<br />
数<br />
选<br />
。<br />
节<br />
节<br />
(intrinsic 函 function)<br />
间<br />
的 位 置 进 行 插 值 。<br />
。<strong>CUDA</strong> 分<br />
4.3.4.3 来 自 线 性 存 储 器 的 纹 理 与 来 自 <strong>CUDA</strong> 数 组 的 纹 理<br />
于 一 维 纹 理 执 行 简 单 的 线 性 插 值 , 而 对 于 二 维 纹 理 则 执 行 双 线 性 插 值 。 对<br />
texel 纹 理 拾 取 位 置 周 围 的 于 位<br />
texel 取 , 纹 理 拾 取 的 返 回 值 将 根 据 纹 理 坐 标 在 读 被<br />
D 录 附<br />
了 关 于 纹 理 拾 取 的 更 多 细 节 。 供<br />
<br />
<br />
<br />
<br />
仅 不 维<br />
的 任 意 区 域 ( 参 见 在 线 性 存 储 器 内 分 配 的 纹 理 : 度 仅 能 为 1; 组 纹 理 过 滤 ; 可 使 用 非 归 一 化 整 型 纹 理 坐 标 寻 址 ; 支 持 多 种 寻 址 模 式 : 超 出 范 围 的 纹 理 访 问 将 返 回 零 。<br />
第 4.5.1.2<br />
)。<br />
配 例 程 返 回<br />
4.4 设 备 运 行 时 组 件<br />
cudaBindTexture()/cuTexRefSetAddress()<br />
会 对 纹 理 基 址 实 施 对 齐 要 求 。 为 了 抽 象 这 种 来 自 程 序 员 的 对 齐 要 求 , 绑 定 设 备 存 储 器 上 的 纹 理 参 考 的 函 数 将 传 回 一 个 字 节 偏 移 , 必 须 将 其 到 纹 理 拾 取 , 之 后 才 能 读 取 所 需 的 存 储 器 的 基 址 指 针 符 合 这 种 对 齐 限 制 , 因 此 应 用 程 序 可 通 过 向 件 硬<br />
<strong>CUDA</strong> 可 以 是 线 性 存 储 器 或 理 纹<br />
4.4.1 数 学 函 数<br />
递 所 分 配 的 指 针 来 完 全 避 免 偏 移 传<br />
备 运 行 时 组 件 仅 可 用 于 设 备 函 数 设<br />
误 差 范 围 。<br />
B.1 于 对<br />
介 绍 的 部 分 函 数 而 言 , 设 备 运 行 时 组 件 中 存 在 准 确 性 略 低 而 速 度 更 快 的 版 本 ; 其 名 称 相 同 ,<br />
。<br />
4.4.2 同 步 函 数<br />
void __syncthreads();<br />
__syncthreads() 用<br />
步 块 中 的 所 有 线 程 。 一 旦 所 有 线 程 均 达 到 此 同 步 点 , 才 将 继 续 执 行 后 续 代 码 。 于 协 调 同 一 个 块 内 的 线 程 间 通 信 。 在 一 个 块 内 的 某 些 线 程 访 问 共 享 或 全 局 存 储 器 中 的 相 同<br />
__syncthreads() 允<br />
地 址 时 , 部 分 访 问 操 作 可 能 存 在 写 入 后 读 取 、 读 取 后 写 入 或 写 入 后 写 入 之 类 的 风 险 。 可 通 过 在 这 些 访 问 操 作 间 同 步 线 程 来 避 免 这 些 数 据 风 险 。 许 在 条 件 代 码 中 使 用 , 但 仅 当 条 件 估 值 在 整 个 线 程 块 中 都 相 同 时 才 允 许 使 用 , 否 则 代 码 执 行 将 有 可 能 挂 起 , 或 者 出 现 意 料 之 外 的 副 作 用 。 同<br />
(-use_fast_math) 器 有 一 个 译 编<br />
项 , 用 于 强 制 要 求 所 有 函 数 编 译 其 准 确 性 略 低 的 版 本 ( 如 果 存 在 )。<br />
但 带 有 一 个 __<br />
__sinf(x))。B.2 如 ( 缀<br />
列 举 了 这 些 内 建<br />
数 , 还 列 举 了 它 们 的 对 应<br />
20 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
列<br />
数<br />
(atomic<br />
,atomicAdd() 将 对 function)<br />
元<br />
元<br />
和<br />
访<br />
节<br />
位<br />
位 位<br />
修<br />
写<br />
4.4.3 纹 理 函 数<br />
4.4.3.1 来 自 线 性 存 储 器 的 纹 理<br />
系<br />
template<br />
Type tex1Dfetch(<br />
texture texRef,<br />
int x);<br />
float tex1Dfetch(<br />
texture texRef,<br />
int x);<br />
float tex1Dfetch(<br />
texture texRef,<br />
int x);<br />
float tex1Dfetch(<br />
texture texRef,<br />
int x);<br />
float tex1Dfetch(<br />
texture texRef,<br />
int x);<br />
拾<br />
的<br />
tex1Dfetch() 来 自 线 性 存 储 器 的 纹 理 , 通 过 于 对<br />
函 数 访 问 纹 理 , 示 例 如 下 : 列<br />
float4 tex1Dfetch(<br />
texture texRef,<br />
说 , 这 些 函 数 可 选 择 将 整 型 转 变 为 单 精 度 浮 点 类 型 。 来 型 整 于 对 。 式<br />
int x);<br />
拾<br />
的<br />
4.4.3.2 来 自 <strong>CUDA</strong> 数 组 的 纹 理<br />
x 函 数 会 使 用 纹 理 坐 标 些 这<br />
texRef 定 到 纹 理 参 考 绑 取<br />
线 性 存 储 器 区 域 。 不 支 持 纹 理 过 滤 和 寻 址 模<br />
2 上 述 函 数 以 外 , 还 支 持 了 除<br />
4 和 组<br />
, 示 例 如 下 : 组<br />
template<br />
Type tex1D(texture texRef,<br />
float x);<br />
template<br />
Type tex2D(texture texRef,<br />
float x, float y);<br />
template<br />
Type tex3D(texture texRef,<br />
float x, float y, float z);<br />
和<br />
拾<br />
的<br />
数<br />
x 示 例 将 使 用 纹 理 坐 标 上 以<br />
texRef 定 到 纹 理 参 考 绑 取<br />
性 存 储 器 。 线<br />
<strong>CUDA</strong> 来 自 于 对<br />
tex1D()、tex2D()、tex3D() 纹 理 , 可 通 过 的 组<br />
纹 理 : 问<br />
4.4.4 原 子 函 数<br />
。 纹 理 参 考 的 不 变 ( 编 译 时 ) 和 可 变 ( 运 行 时 ) 属 性 相 互 结 合 , 共 同 确 定 坐 标 的 解 释 方 式 、 在 纹 理 拾 取 过 程 中 发 生 的 处 理 以 及 纹 组<br />
将 结 果 写 回 同 一 地 址 。 之 所 以 说 这 样 的 操 作 是 原 子 的 , 是 因 为 它 可 在 不 干 扰 其 他 线 程 的 前 提 下 执 行 。 换 句<br />
<strong>CUDA</strong> 编<br />
21<br />
x、y 函 数 将 使 用 纹 理 坐 标 些 这<br />
z<br />
texRef 定 到 纹 理 参 考 绑 取<br />
<strong>CUDA</strong><br />
4.3.4.1 取 所 提 供 的 返 回 值 ( 参 见 第 拾 理<br />
第 4.3.4.2<br />
)。<br />
原 子 函 数<br />
32 全 局 或 共 享 存 储 器 内 的 一 个 于 位<br />
或 64<br />
- 行 读 取 执 字<br />
- 入 原 子 改<br />
2.0 南 , 版 本 指 程<br />
操 作 。 例 如<br />
32 局 或 共 享 存 储 器 内 的 某 个 地 址 读 取 全 在<br />
字 , 将 其 与 一 个 整 型 相 加 , 并<br />
说 , 在 操 作 完 成 前 , 其 他 任 何 线 程 都 无 法 访 问 此 地 址 。 话<br />
C 录 附<br />
举 了 受 支 持 的 所 有 原 子 函 数 。 如 附 录 所 述 , 并 非 所 有 设 备 都 支 持 这 些 函 数 。 具 体 来 说 , 计 算 能
的<br />
块<br />
块<br />
,<strong>CUDA</strong> 驱<br />
都<br />
的 和<br />
运<br />
节 配<br />
是<br />
是<br />
需<br />
动<br />
动<br />
。<br />
。<br />
节<br />
是<br />
对<br />
。 数<br />
驱<br />
均<br />
零 时 返 回 非 零 值 。 非 零 时 返 回 非 零 值 。 非<br />
节<br />
的<br />
节<br />
前<br />
前<br />
。nvcc<br />
运 生<br />
宿<br />
驱<br />
的<br />
4.4.5 Warp vote 函 数<br />
用 于 有 符 号 和 无 符 号 整 型 ( 适 仅 作 操 子 原<br />
函 数<br />
备 不 支 持 任 何 原 子 函 数 设<br />
或<br />
int __all(int predicate);<br />
vote 函<br />
int __any(int predicate);<br />
1.0 为 力<br />
一 个 例 外 情 况 , 它 支 持 单 精 度 浮 点 数 )。<br />
但 atomicExch()<br />
的 所 有 线 程 计<br />
4.5 宿 主<br />
内<br />
宿 主 运 行 时 组 件<br />
当 1.2 计 算 能 力 为 有 只<br />
Warp 的 设 备 支 持 高 更<br />
为 warp<br />
<br />
<br />
<br />
<br />
<br />
代 设<br />
<br />
<br />
上 存 纹 执<br />
与<br />
有 宿 主 函 数 才 能 使 用 宿 主 运 行 时 组 件 备 管 理 只<br />
文 储 器 管 理 ; 下<br />
算 predicate,<br />
predicate 当 所 有 线 程 的 仅 且<br />
为 warp<br />
的 所 有 线 程 计 算 predicate, 内<br />
predicate 当 任 意 线 程 的 仅 且<br />
提 供 了 具 有 以 下 功 能 的 函 数 :<br />
; 它<br />
模 块 管 理 ; 行 控 制 码<br />
<br />
一<br />
参 考 管 理 ; 互 操 作 性 驱 动 程 的 理<br />
的 是 运<br />
<strong>CUDA</strong> 运<br />
OpenGL<br />
Direct3D<br />
包 含 两 个 API: 它<br />
。<br />
<strong>CUDA</strong> 称 为 个 一<br />
础 之 上 实 现 的 成 基<br />
序 API<br />
级 API; 低<br />
<strong>CUDA</strong> 为 称 个<br />
API 时 行<br />
级 API, 高<br />
<strong>CUDA</strong> 在 是<br />
API 序 程 动<br />
。<br />
API 个 两 这<br />
互 斥 的 : 一 个 应 用 程 序 仅 能 使 用 其 中 之 一 行 时 提 供 了 隐 式 初 始 化 、 上 下 文 管 理 和 模 块 管 理 , 从 而 简 化 了 设 备 代 码 管 理 它<br />
的 C<br />
<strong>CUDA</strong> 码 基 于 代 主<br />
<strong>CUDA</strong> 驱<br />
4.2.5 ( 请 参 见 第 时 行<br />
。<br />
相 反<br />
API。<br />
<strong>CUDA</strong> 运<br />
API 序 程 动<br />
<strong>CUDA</strong> 此 链 接 到 此 代 码 的 应 用 程 序 必 须 使 用 因 ),<br />
时 行<br />
22 <strong>CUDA</strong><br />
提 供 了 枚 举 系 统 上 可 用 设 备 、 查 询 其 属 性 、 为 内 核 执 行 选 择 一 个 设 备 的 函 数 ( 运 行 编<br />
cubin 还 具 有 独 立 于 语 言 的 特 点 , 因 为 它 仅 处 理 外 此<br />
4.5.1 一 般 概 念<br />
4.2.5 请 参 见 第 ( 象<br />
<strong>CUDA</strong> 体 来 说 , 使 用 具 )。<br />
API 程 序 动 驱<br />
的 代 码 数 量 更 多 , 编 程 和 调 试 更 加 困 难 , 但 提 供 了 更 出 色 的 控 制 级 别 , 置 和 启 动 内 核 的 难 度 更 大 , 因 为 执 行 配 置 和 内 核 参 数 必 须 通 过 显 式 函 数 调 用 来 指 定 , 而 要<br />
库 提 供 的 , 其 所 有 入 口 点 都 带 缀 。 态<br />
4.2.3 利 用 第 能 不<br />
态 库 提 供 的 , 其 所 有 入 口 点 都 带<br />
4.5.2.9 的 执 行 配 置 语 法 。 此 外 , 设 备 模 拟 ( 请 参 见 第 绍 介<br />
<strong>CUDA</strong> 适 用 于 不 )<br />
有 cuda<br />
程 序 API。 动<br />
API 序 程 动<br />
nvcuda 过 通<br />
4.5.1.1 设 备<br />
有 cu<br />
API 时 行<br />
cudart 过 通<br />
2.0 南 , 版 本 指 程<br />
API 种 两<br />
时 API
Direct3D 互 。<br />
节<br />
和<br />
函<br />
节<br />
,Direct3D<br />
位<br />
节<br />
的<br />
(linear 或 memory)<br />
9.0。<br />
和<br />
实<br />
数<br />
,<strong>CUDA</strong><br />
启<br />
节<br />
)。<br />
arrays)。<br />
(<strong>CUDA</strong><br />
节<br />
。<strong>CUDA</strong><br />
与<br />
、16<br />
数<br />
个<br />
4.5.1.2 存 储 器<br />
程 可 在 同 一 个 设 备 上 执 行 设 备 代 码 , 但 根 据 设 计 , 一 个 宿 主 线 程 只 能 在 一 个 设 备 上 执 行 设 备 代 线 主 宿 个 多<br />
存 储 器<br />
4.5.2.2 内 容 请 参 见 第 关 相<br />
API 动 程 序 驱 ,<br />
4.5.3.2 内 容 请 参 见 第 关 相<br />
<strong>CUDA</strong> 数<br />
<strong>CUDA</strong> 因 而 , 需 要 多 个 在 多 个 设 备 上 执 行 设 备 代 码 。 此 外 , 通 过 一 个 宿 主 线 程 的 运 行 时 创 建 的 资 源 无 法 由 来 自 其 他 宿 主 线 程 的 运 行 时 使 用 。 。 码<br />
32 位<br />
位<br />
个<br />
支<br />
位<br />
数<br />
位<br />
位<br />
设 备 存 储 器 可 指 派 为 线 性 存 储 器<br />
<strong>CUDA</strong><br />
组<br />
32 上 的 线 性 存 储 器 位 于 备 设<br />
地 址 空 间 内 , 因 此 , 独 立 分 配 的 实 体 可 通 过 指 针 引 用 另 外 一 个 实 体 , 比 如 ,<br />
4.3.4 存 储 器 布 局 是 不 透 明 , 专 为 纹 理 拾 取 而 优 化 ( 参 见 第 的 组<br />
)。 它 们 可 以 是 一 维 、 二 维 或<br />
分<br />
1、2、4 的 , 由 元 素 组 成 , 这 些 元 素 包 含 维 三<br />
8 , 这 些 分 量 可 以 是 有 符 号 或 无 符 号 的 量 分<br />
或<br />
4.5.1.3 OpenGL 互 操 作 性<br />
的 (page-locked)<br />
16 , 也 可 以 是 型 整<br />
API ( 当 前 仅 有 驱 动 程 序 点 浮<br />
32 或 ) 持<br />
浮 点<br />
组 仅 可 由 内 核<br />
OpenGL 缓<br />
(buffer 可 能<br />
object)<br />
使 的<br />
节<br />
能<br />
实 写<br />
4.5.2.3 可 通 过 第 主 宿<br />
第 4.5.3.6<br />
<strong>CUDA</strong> 的 存 储 器 复 制 函 数 读 取 和 写 入 线 性 存 储 器 和 绍 介<br />
。 组<br />
储 器 和 设 备 存 储 器 之 间 的 带 宽 较 高 —— 但 仅 针 对 宿 主 存 储 器 的 宿 主 线 程 所 执 行 的 数 据 传 输 。 分 页 锁 定 的 存 储 器 是 一 种 稀 缺 资 源 , 因 此 分 页 锁 定 存 储 器 中 的 分 配 将 先 于 可 分 页 存 储 器 的 分 配 而 出 错 。 此 外 , 由 于 减 少 了 操 作 系 统 可 用 于 分 页 的 物 理 存 储 器 数 量 , 分 配 过 多 的 分 页 锁 定 存 储 器 将 降 低 整 体 系 统 性 能 。 存<br />
分 页 存 储 器 恰 好 相 反 。 分 页 锁 定 存 储 器 的 优 势 之 一 在 于 , 如 果 将 宿 主 存 储 器 指 派 为 分 页 锁 定 存 储 器 , 宿 主<br />
宿 主 运 行 时 还 提 供 了 函 数 来 分 配 和 释 放 分 页 锁 定<br />
— 存 储 器 主 宿<br />
malloc()<br />
配 的 普 通 可<br />
二 进 制 树 内 。 在<br />
过 纹 理 拾 取 读 取 , 仅 可 绑 定 到 具 有 相 同 分 量 数 的 纹 理 参 考 。 通<br />
4.5.1.4 Direct3D 互 操 作 性<br />
Direct3D<br />
<strong>CUDA</strong> 能 资<br />
使 实 的<br />
节<br />
能<br />
实 写<br />
使<br />
冲 对 象<br />
<strong>CUDA</strong> 到 射 映<br />
<strong>CUDA</strong> 空 间 , 从 而 使 址 地<br />
OpenGL 取 读 够<br />
入<br />
<strong>CUDA</strong> 据 或 使 数 的<br />
OpenGL 入 数 据 供 写 够<br />
4.5.2.7 第 。 用<br />
API 了 如 何 通 过 运 行 时 述 描<br />
现 此 目<br />
4.5.3.10 第 , 标<br />
API 了 如 何 通 过 驱 动 程 序 述 描<br />
此 目 标 。 现<br />
cuD3D9RegisterResource() 参<br />
API 了 如 何 通 过 驱 动 程 序 现 此 目 标 对 于 可 映 射 哪 些 资 源 的 限 制 条 件 , 请 参 考 手 册 。 介 绍<br />
设 设<br />
<strong>CUDA</strong><br />
GPU 上 上<br />
上 见<br />
cudaD3D9RegisterResource()<br />
目 标 , 同 一 节 还 和 此 现<br />
设<br />
标<br />
文 一 次 仅 可 与 一 创 建 的 。 此 外 下<br />
备 互 操 作<br />
下 文<br />
备 必 须 是 在 同 一<br />
<strong>CUDA</strong> 映 射 到 可 源<br />
地 址 空 间 , 从 而<br />
使 <strong>CUDA</strong><br />
Direct3D 取 读 够<br />
入 的 数 据 , 或 者<br />
记<br />
Direct3D 入 数 据 供 写 够<br />
4.5.2.8 第 。 用<br />
API 了 如 何 通 过 运 行 时 述 描<br />
<strong>CUDA</strong> 编<br />
为 了 促 进 宿 主 和 设 备 之 间 的 并 发 执 行 , 某 些 运 行 时 函 数 是 异 步 的 : 控 制 将 在 设 备 完 成 所 请 求 的 任 务 之 前 返<br />
23<br />
操 作 性 目 前 仅 支<br />
4.5.1.5 异 步 并 发 执 行<br />
<br />
执 通<br />
后<br />
个 Direct3D<br />
持 Direct3D<br />
和 Direct3D<br />
回 应 用 程 序 。 此 类 函 数 包 括<br />
D3DCREATE_HARDWARE_VERTEXPROCESSING 创 建 时 必 须 使 用 在 备<br />
:<br />
过 __global__<br />
cuLaunchGrid() 或 数<br />
cuLaunchGridAsync()<br />
的 内 核 ; 动<br />
2.0 南 , 版 本 指 程<br />
Async 储 器 复 制 和 带 有 存 行<br />
的 函 数 ; 缀
节 来<br />
不<br />
(stream)<br />
后<br />
应<br />
实<br />
和<br />
;<br />
提 的 和 的<br />
将 的<br />
节 实<br />
环<br />
来 调 并<br />
节<br />
节<br />
数<br />
的<br />
操<br />
的<br />
实<br />
的 使 的<br />
和<br />
实<br />
应<br />
<br />
设 执<br />
设 备 与 设 备 间 双 向 存 储 器 复 制 的 函 数 置 存 储 器 的 函 数 。 某 些 设 备 还 可 在 分 页 锁 定 的 宿 主 存 储 器 和 设 备 存 储 器 之 间 执 行 复 制 , 且 与 内 核 执 行 并 发 地 执 行 此 类 复 制 操 行<br />
4.5.2.4 节<br />
。 如 果 使 用 的 是 运 行 时 API,<br />
则 请 参 请 ) 分 配 的 二 维 数 组 的 存 储 器 复 制 。 作<br />
流 的 定 义 方 法 是 创 建 流 对 象 , 并 将 其 指 定 为 内 核 启 动 和 宿 主 与 设 备 间 内 存 双 向 复 制 序 列 的 流 参 数 。 管<br />
的<br />
为<br />
第<br />
cudaGetDeviceProperties() 序 可 通 过 调 用 程 用<br />
deviceOverlap 查 检<br />
询 此 功 能 ; 如 果 使 用 的 是 驱 动 程 序 API, 查<br />
CU_DEVICE_ATTRIBUTE_GPU_OVERLAP 过 使 用 通 可<br />
用 cuDeviceGetAttribute()<br />
<strong>CUDA</strong> 。 此 功 能 当 前 仅 支 持 不 涉 及 询 查<br />
或 通 过 cudaMallocPitch()( 组<br />
4.5.2.3 第 见<br />
或 cuMemAllocPitch()( )<br />
4.5.3.6 第 见 参<br />
用 程 序 通 过 流 理 并 发 。 流 就 是 按 顺 序 执 行 的 一 系 列 操 作 。 另 一 方 面 , 不 同 的 流 可 与 其 他 流 乱 序 执 行 其 操 作 , 也 可 并 发 执 行 。 应<br />
API 了 如 何 通 过 运 行 时 述 描<br />
4.5.3.7 目 标 , 第 此 现<br />
API 了 如 何 通 过 驱 动 程 序 述 描<br />
现 此 目<br />
。 不 带 流 参 数 或 使 用 零 作 为 流 参 数 的 任 何 内 核 启 动 、 存 储 器 设 置 或 存 储 器 复 制 函 数 都 仅 能 在 此 前 的 操 作 完 成 标<br />
API<br />
始 包 括 作 为 流 部 分 的 操 作 , 而 在 此 类 函 数 完 成 之 前 , 无 法 启 动 任 何 后 续 操 作 。 无 流 参 数 的 内 核 启 动 , 缀 的 存 储 器 复 制 都 将 被 指 派 给 默 认 零 流 种 方 法 , 使 其 能 够 了 解 一 个 流 中 的 之 前 全 部 操 作 是 否 已 完 成 。 用 于 运 行 时 开 后<br />
无 Async<br />
有 操 作 完 成 。 类 似 地 , 用 于 运 行 所<br />
API 运 行 时 于 用<br />
cudaStreamQuery()<br />
用 于 驱 动 程<br />
应 用 程 序 提 供 了 一<br />
序 API<br />
cuStreamQuery()<br />
cudaStreamSnchronize()<br />
API 于 驱 动 程 序 用 和<br />
cuStreamSynchronize()<br />
了 一 种 方 法 , 可 显 式 强 制 要 求 运 行 时 等 待 流 中 之 前 的 应 用 程 序 能 够 强 制 要 求 运 行 时 等 待 所 有 流 中 的 所 有 之 前 设 备 任 务 完 成 。 为 了 避 免 不 必 要 的 减 速 , 最 好 将 这 些 供<br />
待 给 定 流 内 之 前 的 所 有 任 务 完 成 , 之 后 再 销 毁 流 , 并 将 控 制 返 回 给 等<br />
操<br />
时 API<br />
cudaThreadSynchronize()<br />
API 驱 动 程 序 于 用<br />
cuCtxSynchronize()<br />
API 序 宿 主 线 程 。 运 行 时 还 提 供 了 一 种 方 法 , 可 密 切 监 控 设 备 的 进 度 并 执 行 准 确 的 计 时 , 它 允 许 应 用 程 序 异 步 记 录 程 序 内 任 意 点 的 事 件 , 并 查 询 这 些 事 件 的 实 际 记 录 事 件 。 一 个 事 件 将 在 先 于 该 事 件 的 所 有 任 务 ( 也 可 以 是 给 定 流 中 程 动<br />
cuStreamDestroy()<br />
函 数 用 于 计 时 或 者 隔 离 失 败 的 启 动 或 存 储 器 复 制 操 作 。 用 于 运 行 时 API<br />
cudaStreamDestroy()<br />
用 于 驱<br />
4.5.2 运 行 时 API<br />
果 宿 主 线 程 在 来 自 不 同 流 的 两 项 操 作 之 间 调 了 分 页 锁 定 的 宿 主 存 储 器 分 配 、 设 备 存 储 器 分 配 、 设 备 存 局 禁 用 异 步 执 行 。 此 特 性 仅 为 调 试 提 供 , 不 应 用 于 使 生 产 软 件 更 可 靠 运 行 之 目 的 。 如<br />
/ 有 操 作 ) 均 已 完 成 时 记 录 。 零 流 中 的 事 件 将 在 设 备 完 成 来 自 所 有 流 的 之 前 任 务 作 后 记 录 。 所 的<br />
第 4.5.2.5<br />
4.5.2.1 初 始 化<br />
API 描 述 如 何 通 过 运 行 时 将 节<br />
4.5.3.8 目 标 , 第 此 现<br />
API 述 如 何 通 过 驱 动 程 序 描 将<br />
此 目 标 。 现<br />
<strong>CUDA</strong> 设 置 、 设 备 与 设 备 之 间 的 双 向 存 储 器 复 制 或 零 流 的 任 何 器 储<br />
, 则 这 两 项 操 作 无 法 并 行 执 行 。 作<br />
4.5.2.2 设 备 管 理<br />
<strong>CUDA</strong>_LAUNCH_BLOCKING 员 可 将 序 程<br />
变 量 设 置 为 1, 从 而 为 系 统 上 运 行 的 所 境<br />
有 <strong>CUDA</strong><br />
用 程 序 全<br />
cudaGetDeviceCount() 和<br />
提<br />
API 时 行 运<br />
存 在 显 式 初 始 化 函 数 ; 它 将 在 运 行 时 函 数 被 首 次 调 用 时 初 始 化 。 需 要 牢 记 , 在 计 时<br />
int deviceCount;<br />
cudaGetDeviceCount(&deviceCount);<br />
其 属 性 : 索<br />
24 <strong>CUDA</strong> 编<br />
运 行 时 调 用 发 生 时 , 或 解 释 来 自 第 一 次 运 行 时 调 用 的 错 误 码 时 , 即 进 行 初 始 化 。<br />
(timing)<br />
cudaGetDeviceProperties()<br />
供 了 一 种 方 法 , 用 于 枚 举 这 些 设 备 并 检<br />
2.0 南 , 版 本 指 程
的<br />
分<br />
个<br />
、cudaMallocPitch() 分<br />
数<br />
。 用<br />
节<br />
、<strong>CUDA</strong> 数<br />
int device;<br />
for (device = 0; device < deviceCount; ++device) {<br />
cudaDeviceProp deviceProp;<br />
cudaGetDeviceProperties(&deviceProp, device);<br />
}<br />
cudaSetDevice() 于 选 择 与 宿 主 线 程 相 关 的 设 备 : 用<br />
cudaSetDevice(device);<br />
cudaSetDevice() 完<br />
函<br />
的 4.5.2.3 存 储 器 管 理<br />
或<br />
分<br />
: 释<br />
成 此 任 务 , 将 自 动 选 中 设<br />
__global__ 首 先 选 择 设 备 , 之 后 才 能 调 用 须 必<br />
API 任 何 来 自 运 行 时 或 数<br />
数 。 如 果 未 通 过 显 式 调 任 何 显 式 调 用 都 将 无 效 函<br />
cudaSetDevice() 随 后 对 0, 备<br />
float* devPtr;<br />
cudaMalloc((void**)&devPtr, 256 * sizeof(float));<br />
// host code<br />
float* devPtr;<br />
int pitch;<br />
点 元 素 的 数 组 因<br />
cudaMallocPitch((void**)&devPtr, &pitch,<br />
浮<br />
width * sizeof(float), height);<br />
myKernel(devPtr, pitch);<br />
// device code<br />
__global__ void myKernel(float* devPtr, int pitch)<br />
{<br />
for (int r = 0; r < height; ++r) {<br />
float* row = (float*)((char*)devPtr + r * pitch);<br />
for (int c = 0; c < width; ++c) {<br />
float element = row[c];<br />
}<br />
}<br />
}<br />
<strong>CUDA</strong><br />
cudaCreateChannelDesc() 创 分 数<br />
释<br />
。 放<br />
。cudaMallocArray() 需<br />
cudaMalloc() 存 储 器 是 使 用 性 线<br />
cudaMallocPitch()<br />
cudaFree() , 使 用 的 配<br />
256 示 例 代 码 将 在 线 性 存 储 器 中 分 配 一 个 包 含 下 以<br />
议 在 分 配 二 维 数 组 时 使 用 cudaMallocPitch(), 建<br />
5.1.2.1 能 确 保 合 理 填 充 已 分 配 的 存 储 器 , 满 足 第 它 为<br />
绍 的 对 齐 要 求 , 从 而 确 保 访 问 行 地 址 或 执 行 二 维 数 组 与 设 备 存 储 器 的 其 他 区 域 之 间 的 复 制 ( 使 用<br />
cudaMemcpy2D()) 时 获 得 最 优 性 能 。 所 返 回 的 间 距 ( 或 步 幅 ) 必 须 用 于 访 问 数 组 元 素 。 以 下 代 码 示 例 将 分 介<br />
widthxheight 个 一 配<br />
维 浮 点 值 数 组 , 并 显 示 如 何 在 设 备 代 码 中 循 环 遍 历 数 组 元 素 : 二<br />
的<br />
数<br />
位<br />
cudaChannelFormatDesc channelDesc =<br />
cudaCreateChannelDesc();<br />
cudaArray* cuArray;<br />
cudaMallocArray(&cuArray, &channelDesc, width, height);<br />
cudaGetSymbolAddress() 用<br />
的 格 式 描 述 。 建<br />
获<br />
cudaMallocArray() 使 用 是 组<br />
cudaFreeArray() , 使 用 的 配<br />
放<br />
使 用 要<br />
考 手 册 列 举 了 用 于 配 的 线 性 存 储 器 组 和 为 全 局 或 常 量 存 储 器 空 间 中 声 明 的 变 量 分 配 的 存 储 器 之 间 复 制 存 储 器 的 所 有 函 数 。 参<br />
widthxheight 代 码 示 例 分 配 了 一 个 下 以<br />
<strong>CUDA</strong><br />
32 包 含 一 个 , 组<br />
浮 点 组 件 : 的<br />
cudaGetSymbolSize()<br />
索 指 向 为 全 局 存 储 器 空 间 中 声 明 的 变 量 分 配 的 存 储 器 的 地 址 。 所 分 配 存 储 器 的 大 小 是 通 过 取 的 。<br />
cudaMemcpy2DToArray(cuArray, 0, 0, devPtr, pitch,<br />
检 于<br />
width * sizeof(float), height,<br />
cudaMemcpyDeviceToDevice);<br />
<strong>CUDA</strong> 编<br />
:<br />
25<br />
在 cudaMalloc()<br />
配 的 线 性 存 储 器<br />
float data[256];<br />
代 码 示 例 将 一 些 宿 主 存 储 器 数 组 复 制 到 设 备 存 储 器 中 的 面 下<br />
int size = sizeof(data);<br />
float* devPtr;<br />
cudaMalloc((void**)&devPtr, size);<br />
<strong>CUDA</strong> 的 代 码 示 例 将 二 维 数 组 复 制 到 之 前 代 码 示 例 中 分 配 的 面 下<br />
中 : 组<br />
2.0 南 , 版 本 指 程
。hostPtr<br />
cudaMemcpy(devPtr, data, size, cudaMemcpyHostToDevice);<br />
__constant__ float constData[256];<br />
float data[256];<br />
cudaMemcpyToSymbol(constData, data, sizeof(data));<br />
4.5.2.4 流 管 理<br />
面 的 代 码 示 例 将 一 些 宿 主 存 储 器 数 组 复 制 到 常 量 存 储 器 中 : 下<br />
cudaStream_t stream[2];<br />
for (int i = 0; i < 2; ++i)<br />
cudaStreamCreate(&stream[i]);<br />
:<br />
for (int i = 0; i < 2; ++i)<br />
cudaMemcpyAsync(inputDevPtr + i * size, hostPtr + i * size,<br />
size, cudaMemcpyHostToDevice, stream[i]);<br />
for (int i = 0; i < 2; ++i)<br />
myKernel<br />
(outputDevPtr + i * size, inputDevPtr + i * size, size);<br />
for (int i = 0; i < 2; ++i)<br />
cudaMemcpyAsync(hostPtr + i * size, outputDevPtr + i * size,<br />
size, cudaMemcpyDeviceToHost, stream[i]);<br />
cudaThreadSynchronize();<br />
数 的<br />
下 代 码 示 例 创 建 两 个 流 这 些 流 均 通 过 以 下 代 码 示 例 定 义 为 一 个 任 务 序 列 , 包 括 一 次 从 宿 主 到 设 备 的 存 储 器 复 制 、 一 次 内 核 启 动 、 以<br />
次 从 设 备 到 宿 主 的 存 储 器 复 制 : 一<br />
myKernel()<br />
允 处<br />
复<br />
必 的<br />
float* hostPtr;<br />
器 , 这 样 才 能 同 时 执 行 : 储 存 主<br />
cudaMallocHost((void**)&hostPtr, 2 * size);<br />
hostPtr 流 均 会 将 其 输 入 数 组 个 两<br />
inputDevPtr 分 复 制 到 设 备 存 储 器 的 部 一<br />
中 , 通 过 调 用 组<br />
cudaStreamSynchronize()<br />
cudaStreamDestroy() 可 可<br />
并<br />
目<br />
设 备 上 的 inputDevPtr, 理<br />
outputDevPtr 果 结 将<br />
hostPtr 回 制<br />
相 同 部 分 。 使 用 两 个 流<br />
4.5.2.5 事 件 管 理<br />
hostPtr 理 处<br />
许 一 个 流 的 存 储 器 复 制 与 另 外 一 个 流 的 内 核 执 行 相 互 重 叠<br />
须 指 向 分 页 锁 定 的 宿<br />
cudaEvent_t start, stop;<br />
cudaEventCreate(&start);<br />
cudaEventCreate(&stop);<br />
:<br />
于 同 步 宿 主 与 特 定 流 , 允 许 其 他 流 继 续 在 该 设 备 上 执 行 。 通 过 调 用 释 放 流 。 用<br />
后 调 用 了 cudaThreadSynchronize(), 最<br />
的 是 在 进 一 步 处 理 之 前 确 定 所 有 流 均 已 完 成 。<br />
cudaEventRecord(start, 0);<br />
for (int i = 0; i < 2; ++i)<br />
cudaMemcpyAsync(inputDev + i * size, inputHost + i * size,<br />
size, cudaMemcpyHostToDevice, stream[i]);<br />
for (int i = 0; i < 2; ++i)<br />
myKernel<br />
(outputDev + i * size, inputDev + i * size, size);<br />
for (int i = 0; i < 2; ++i)<br />
cudaMemcpyAsync(outputHost + i * size, outputDev + i * size,<br />
size, cudaMemcpyDeviceToHost, stream[i]);<br />
cudaEventRecord(stop, 0);<br />
cudaEventSynchronize(stop);<br />
float elapsedTime;<br />
cudaEventElapsedTime(&elapsedTime, start, stop);<br />
面 的 代 码 示 例 创 建 了 两 个 事 件 这 些 事 件 可 用 于 为 上 一 节 的 代 码 示 例 计 时 , 方 法 如 下 : 下<br />
cudaEventDestroy(start);<br />
cudaEventDestroy(stop);<br />
26 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
定<br />
类<br />
,cudaFilterModeLinear 是<br />
<br />
<br />
在<br />
cudaChannelFormatKindUnsigned, 在<br />
(bit)<br />
cudaChannelFormatKindSigned,<br />
指<br />
定<br />
;channelDesc 的<br />
为<br />
类<br />
;addressMode 是<br />
(wrap)<br />
或<br />
;filterMode<br />
)texel 的<br />
的<br />
:<br />
和<br />
4.5.2.6 纹 理 参 考 管 理<br />
<br />
高<br />
<br />
struct textureReference<br />
{<br />
int normalized;<br />
enum cudaTextureFilterMode filterMode;<br />
enum cudaTextureAddressMode addressMode[3];<br />
struct cudaChannelFormatDesc channelDesc;<br />
}<br />
Normalized<br />
纹 理 坐 标 寻 址 , 而 指<br />
depth<br />
filterMode<br />
cudaFilterModePoint<br />
指 是<br />
纹 理 大 小 ; 定 过 滤 模 式 , 即 拾 取 根 据 输 入 的 纹 理 坐 标 计 算 的 纹 理 时 如 何 返 回 值 或 或<br />
的 纹 理 , 如 下<br />
1]<br />
型<br />
围 内 的 范<br />
于 所 返 回 的 值 为 纹 理 等<br />
级 API<br />
texture 的 义<br />
API 一 种 公 开 继 承 自 低 级 是 型<br />
textureReference 的 义<br />
其<br />
[0, 理 坐 标 是 否 为 归 一 化 形 式 ; 如 果 非 零 , 纹 理 中 的 所 有 元 素 都 将 使 用 纹 定<br />
非 [0,width-1]、[0,height-1]<br />
[0,depth-1],<br />
width、height 的 中<br />
<br />
addressMode 指<br />
如 输 入 纹 理 坐 标 的 两 个 ( 针 对 一 维 纹 理 )、 四 个 ( 针 对 二 维 纹 理 ) 或 八 个 ( 针 对 三 维 纹 理 如<br />
组 , 其 第 一 个 、 第 二 个 和 第 三 个 元 素 分 别 指 定 第 一 个 、 第 二 个 和 第 三 个 纹 理 坐 标 的 寻 址 模 式 ; 寻 址 模<br />
线 性<br />
则 所 返 回 的 值 为 纹 理 坐 标 最 接 近 则<br />
cudaFilterModeLinear;<br />
等 于 cudaFilterModePoint, 果<br />
标 最 接 近 输 入 纹 理 坐 标 的 texel; 坐<br />
等 于 cudaFilterModeLinear, 果<br />
channelDesc 描<br />
struct cudaChannelFormatDesc {<br />
int x, y, z, w;<br />
enum cudaChannelFormatKind f;<br />
};<br />
值 ; 对 于 浮 点 型 的 返 回 值 插<br />
此 此<br />
和<br />
等<br />
述 拾 取 纹 理 时 所 返 回 的 值 的 格 式<br />
型 如 下 : 类<br />
一 的 有 效 值 。 惟<br />
到 (clamp)<br />
到<br />
这 些 分 量 是 有 符 号 整 型 时 ; 这 些 分 量 是 无 符 号 整 型 时 ; :<br />
定 寻 址 模 式 , 表 明 如 何 处 理 超 出 范 围 的 纹 理 坐 标<br />
3 大 小 为 个 一<br />
数<br />
可 等 于 cudaAddressModeClamp, 式<br />
时 超 出 范 围 的 纹 理 坐 标 将 被 调 整<br />
有 效 范 围 之 内 , 也<br />
等 于 cudaAddressModeWrap, 可<br />
时 超 出 范 围 的 纹 理 坐 标 将 被 限 定<br />
效 范 围 之 内 ; 有<br />
于 规 范 化 的 纹 理 坐 标 , 仅 支 持 cudaAddressModeWrap。 对<br />
些 分 量 是 浮 点 类 型 时 。 这<br />
组 的 纹<br />
cudaChannelFormatKindFloat, <br />
normalized、addressMode 和 可 在<br />
数<br />
数<br />
x、y、z 中 其<br />
w<br />
于 返 回 值 各 分 量 的 位<br />
f 而 ,<br />
<br />
<br />
texture texRef;<br />
textureReference* texRefPtr;<br />
cudaGetTextureReference(&texRefPtr, “texRef”);<br />
cudaChannelFormatDesc channelDesc =<br />
cudaCreateChannelDesc();<br />
cudaBindTexture(0, texRefPtr, devPtr, &channelDesc, size);<br />
参 考 。 在 内 核 使 用 纹 理 参 考 从 纹 理 存 储 器 中 读 取 之 前 , 必 须 使 将 纹 理 参 考 绑 定 到 纹 理 。 理<br />
下 代 码 示 例 将 一 个 纹 理 参 考 绑 定 向 的 线 性 存 储 器 : 使 用 低 以<br />
texture texRef;<br />
cudaBindTexture(0, texRef, devPtr, size);<br />
数<br />
filterMode<br />
<strong>CUDA</strong> 在 宿 主 代 码 中 修 改 。 它 们 仅 适 用 于 绑 定 到 接 直<br />
级 API:<br />
<br />
texture texRef;<br />
textureReference* texRefPtr;<br />
cudaGetTextureReference(&texRefPtr, “texRef”);<br />
cudaChannelFormatDesc channelDesc;<br />
<strong>CUDA</strong> 代 码 示 例 将 一 个 纹 理 参 考 绑 定 到 使 用 低 下 以<br />
用 cudaBindTexture()<br />
cudaBindTextureToArray()<br />
<strong>CUDA</strong> 编<br />
27<br />
到 devPtr<br />
组 cuArray:<br />
用 高 级 API: 使<br />
2.0 南 , 版 本 指 程<br />
级 API:
cudaUnbindTexture() 用 。<br />
填<br />
完<br />
及<br />
<br />
cudaGetChannelDesc(&channelDesc, cuArray);<br />
cudaBindTextureToArray(texRef, cuArray, &channelDesc);<br />
texture texRef;<br />
cudaBindTextureToArray(texRef, cuArray);<br />
4.5.2.7 OpenGL 互 操 作 性<br />
GLuint bufferObj;<br />
cudaGLRegisterBufferObject(bufferObj);<br />
返<br />
用 高 级 API: 使<br />
纹 理 绑 定 到 纹 理 参 考 时 指 定 的 格 式 必 须 与 声 明 纹 理 参 考 时 指 定 的 参 数 相 匹 配 ; 否 则 纹 理 拾 取 的 结 果 将 无 法 确 定 于 解 除 纹 理 参 考 的 绑 定 。 将<br />
GLuint bufferObj;<br />
float* devPtr;<br />
cudaGLMapBufferObject((void**)&devPtr, bufferObj);<br />
之<br />
取 完<br />
4.5.2.8 Direct3D 互 操 作 性<br />
先 必 须 将 一 个 缓 冲 对 象 注 册 到 <strong>CUDA</strong>, 首<br />
cudaGLRegisterBufferObject() 能 进 行 映 射 。 可 通 过 才 后<br />
: 成<br />
cudaGLMapBufferObject() 完 成 后 , 内 核 即 可 使 用 册 注<br />
的 设 备 存 储 器 地 址 读 取 或 写 入 缓 冲 对 象 : 回<br />
Direct3D<br />
Direct3D 设 互<br />
指<br />
cudaGLUnmapBufferObject() 映 射 是 通 过 除 解<br />
cudaGLUnregisterBufferObject() , 可 使 用 的 成<br />
注 册 。 消<br />
将<br />
资<br />
LPDIRECT3DVERTEXBUFFER9 buffer;<br />
cudaD3D9RegisterResource(buffer, cudaD3D9RegisterFlagsNone);<br />
LPDIRECT3DSURFACE9 surface;<br />
cudaD3D9RegisterResource(surface, cudaD3D9RegisterFlagsNone);<br />
cudaD3D9RegisterResource()<br />
cudaD3D9UnregisterVertexBuffer()<br />
cudaD3D9MapResources()<br />
有 较 高 的 开 销 , 通 常 仅 为 每 个 资 源 调 用 一 次 。 使 用 可 之 后 , 即 可 在 需 要 时 分 和 任 返 和 具 能 可<br />
。 备<br />
cudaD3D9SetDirect3DDevice() 性 要 求 在 执 行 其 他 任 何 运 行 时 调 用 之 前 通 过 作 操<br />
定<br />
cudaD3D9RegisterResource() 即 可 使 用 后 随<br />
Direct3D<br />
cudaD3D9ResourceGetMappedSize()<br />
cudaD3D9ResourceGetMappedPitchSlice() 返 访 、<br />
回 的 设 备 存 储 器 地 址<br />
注 册 到 <strong>CUDA</strong>: 源<br />
意 多 次 地 映 射 和 解 除 映<br />
<strong>CUDA</strong> 注 册 。 将 资 源 注 册 到 消 取<br />
void* devPtr;<br />
cudaD3D9ResourceGetMappedPointer(&devPtr, buffer);<br />
size_t size;<br />
cudaD3D9ResourceGetMappedSize(&size, buffer);<br />
cudaMemset(devPtr, 0, size);<br />
height) 的<br />
cudaD3D9ResourceGetMappedPointer() 内 核 可 使 用 回 的 大 小 和 间 距 信 息 来 读 取 和 写 入 已 映 射 的 资 源 。 通 问 已 映 射 的 资 源 将 导 致 不 确 定 的 结 果 。 射 。<br />
一 个 缓 冲 区 : 了 充<br />
使 用 别<br />
cudaD3D9UnmapResources()<br />
cudaD3D9ResourceGetMappedPitch()<br />
过 Direct3D<br />
// host code<br />
void* devPtr;<br />
cudaD3D9ResourceGetMappedPointer(&devPtr, surface);<br />
size_t pitch;<br />
cudaD3D9ResourceGetMappedPitch(&pitch, surface);<br />
dim3 Db = dim3(16, 16);<br />
dim3 Dg = dim3((width+Db.x–1)/Db.x, (height+Db.y–1)/Db.y);<br />
myKernel((unsigned char*)devPtr,<br />
width, height, pitch);<br />
// device code<br />
维 表 面 的 一 个 像 素 , 像 素 格 式 为 二<br />
28 <strong>CUDA</strong> 编<br />
0 的 代 码 示 例 使 用 面 下<br />
float4:<br />
(width, 面 的 代 码 示 例 中 , 每 个 线 程 都 访 问 大 小 为 下 在<br />
2.0 南 , 版 本 指 程
mode) emulation<br />
是 用<br />
(printf()<br />
:<br />
选<br />
因 (simulating)。<br />
(device<br />
或<br />
上<br />
。<br />
__global__ void myKernel(unsigned char* surface,<br />
int width, int height, size_t pitch)<br />
{<br />
int x = blockIdx.x * blockDim.x + threadIdx.x;<br />
int y = blockIdx.y * blockDim.y + threadIdx.y;<br />
if (x >= width || y >= height) return;<br />
float* pixel = (float*)(surface + y * pitch) + 4 * x;<br />
}<br />
4.5.2.9 使 用 设 备 模 拟 模 式 进 行 调 试<br />
于 设 备 的 代 码 , 编 程 环 境 未 包 含 任 何 本 地 调 试 支 持 , 但 附 带 了 一 种 设 备 模 拟 模 式 译 , 并 在 宿 主 上 运 行 , 允 许 程 序 员 使 用 宿 主 的 本 地 调 试 支 持 来 调 试 应 用 程 序 , 就 像 调 试 宿 主 应 用 程 序 一 样 。 对<br />
cudaErrorMixedDeviceExecution.<br />
<br />
有 宿<br />
KB 空<br />
<br />
<br />
通<br />
在 内 , 都 必 须 一 致 地 为 设 备 模 拟 或 设 备 执 行 而 编 译 。 将 为 设 备 模 拟 编 译 的 代 码 与 为 设 备 执 行 编 译 的 代 码 相 连 接 将 导 致 初 始 化 时 返 回 以 下 运 行 时 错 误 : 库<br />
设 备 模 拟 模 式 中 运 行 应 用 程 序 时 运 行 时 将 模 拟 编 程 模 型 。 对 于 线 程 块 中 的 每 一 个 线 程 , 运 行 时 都 会 在 宿 主 上 创 建 一 个 线 程 。 程 序 员 需 要 确 保 : 主 能 够 运 行 每 个 块 的 最 大 线 程 数 , 此 外 还 有 一 个 针 对 主 线 程 线 程 。 间 。 在<br />
备 模 拟 模 式 提 供 众 多 特 性 使 之 成 为 一 种 独 具 优 势 的 调 试 工 具 : 过 使 用 宿 主 的 本 地 调 试 支 持 , 程 序 员 即 可 利 用 调 试 程 序 支 持 的 所 有 特 性 , 例 如 设 置 断 点 和 检 查 数 据 。 设<br />
等<br />
出 操 作 或 打 印 到 屏 幕 )。 于 所 有 数 据 都 位 于 宿 主 上 , 因 而 可 从 设 备 或 宿 主 代 码 中 读 取 任 何 特 定 于 设 备 或 特 定 于 宿 主 的 数 据 ; 输<br />
–deviceemu 试 。 在 此 模 式 中 编 译 应 用 程 序 时 ( 使 用 调 于<br />
项 ), 设 备 代 码 将 为 宿 主 编<br />
由<br />
__DEVICE_EMULATION__ 理 宏 处 预<br />
在 此 模 式 中 定 义 的 。 一 个 应 用 程 序 的 所 有 代 码 , 包 括 所 用 的 全 部<br />
由 于 设 备 代 码 被 编 译 为 在 宿 主 上 运 行 , 因 而 可 通 过 无 法 在 设 备 上 运 行 的 代 码 扩 展 代 码 , 如 文 件 输 入 和<br />
如<br />
似 地 , 可 通 过 设 备 或 宿 主 代 码 调 用 任 何 设 备 或 宿 主 函 数 。 果 误 用 了 同 步 函 数 , 运 行 时 将 检 测 到 死 锁 情 况 。 程 序 员 必 须 牢 记 , 设 备 模 拟 模 式 的 目 的 在 于 模 拟 设 备 , 而 非 仿 真 类<br />
而 , 设 备 模 拟 模 式 在 查<br />
<br />
法 错 误 时 非 常 有 用 , 但 可 能 难 以 发 现 某 些 错 误 竞 算 找<br />
<br />
<br />
256 大 的 存 储 器 可 用 于 运 行 所 有 线 程 , 已 知 每 个 线 程 都 要 占 据 堆 栈 中 的 够 足<br />
<br />
<br />
<br />
<br />
使 用<br />
条 件 在 设 备 模 拟 模 式 中 可 能 无 法 体 现 , 因 为 同 时 执 行 的 线 程 数 量 要 比 实 际 设 备 上 少 得 多 争<br />
声 的 编 :<br />
C++<br />
上 编<br />
编<br />
解 除 指 针 对 宿 主 上 的 全 局 存 储 器 的 引 用 或 对 设 备 上 宿 主 存 储 器 的 引 用 时 , 设 备 执 行 几 乎 必 然 以 某 种 无 法 确 定 的 方 式 失 败 而 设 备 模 拟 可 能 会 得 到 正 确 。 大 多 数 时 候 , 相 同 的 浮 点 计 算 在 设 备 上 执 行 时 所 得 到 的 结 果 , 与 在 设 备 模 拟 模 式 在 宿 主 上 执 行 时 所 得 到 的 结 果 并 不 完 全 相 同 。 这 些 情 况 是 可 以 预 见 的 , 只 要 使 用 略 有 差 异 编 译 选 项 , 相 同 的 浮 点 计 在<br />
就 会 得 到 不 同 的 结 果 , 更 不 用 说 不 同 的 编 译 器 、 不 同 的 指 令 集 或 不 同 的 架 构 了 。 具 体 来 说 某 些 宿 主 平 台 会 将 单 精 度 浮 点 计 算 的 中 间 结 果 存 储 在 一 个 扩 展 精 度 寄 存 器 中 在 设 备 模 拟 模 式 中 运 行 时 , 这 可 能 会 造 成 准 确 性 的 显 著 差 异 。 发 生 这 种 情 况 时 , 程 序 员 可 尝 试 以 下 方 法 , 但 没 有 任 何 一 种 算<br />
<strong>CUDA</strong> 编<br />
29<br />
方 法 能 确 保 成 功<br />
unsigned int originalCW;<br />
_FPU_GETCW(originalCW);<br />
unsigned int cw = (originalCW & ~0x300) | 0x000;<br />
_FPU_SETCW(cw);<br />
在<br />
, 从 而 实 施 单 精 度 浮 点 计 算 : 码<br />
使<br />
volatile<br />
一 些 浮 点 变 量 , 实 施 单 精 度 存 储 ; 明<br />
用 gcc<br />
-ffloat-store<br />
器 选 项 ; 译<br />
在 Linux<br />
用 _FPU_GETCW()、 使<br />
Windows<br />
用 _controlfp(), 使<br />
用 以 下 代 码 包 围 目 标 代<br />
unsigned int originalCW = _controlfp(0, 0);<br />
_controlfp(_PC_24, _MCW_PC);<br />
: 用 使 可 也<br />
个<br />
用 Visual<br />
/Op 的 器 译<br />
/fp<br />
器 选 项 ; 译<br />
2.0 南 , 版 本 指 程<br />
24 头 处 , 为 了 存 储 控 制 字 的 当 前 值 并 更 改 它 以 使 尾 数 存 储 在 开 在<br />
中 , 可 使 用 : 位
汇<br />
是<br />
中<br />
位<br />
中<br />
,warp 块<br />
大 内 支<br />
设<br />
进 的<br />
,warp<br />
进<br />
值<br />
_FPU_SETCW(originalCW);<br />
_controlfp(originalCW, 0xfffff);<br />
(denormalized<br />
<br />
vote 函<br />
4.5.3 驱 动 程 序 API<br />
在 结 尾 处 使 用 以 下 代 码 , 恢 复 原 始 控 制 字 : 或<br />
设 备 模 拟 模 式 中 的 大 小 等 于 1。 因 而 同 。 在<br />
数 产 生 的 结 果 将 与 设 备 执 行 模 式 中 不<br />
number)。 这<br />
样 , 对 于 单 精 度 浮 点 数 , 与 计 算 设 备 不 同 ( 请 参 见 附 录 A), 宿 主 平 台 通 常 支 持 反 向 规 格 化 数 可 能 会 导 致 设 备 模 拟 和 设 备 执 行 模 式 下 存 在 显 著 差 异 , 因 为 某 些 计 算 可 能 会 在 一 种 模 式 下 产 生 有 穷 的 结 果 , 而 在 另 一 种 模 式 下 产 生 无 穷 的 结 果 。 同<br />
<strong>CUDA</strong> 驱<br />
中<br />
为 操 纵 对 象 的 函 数 。<br />
大<br />
对 象<br />
句 柄<br />
描 述<br />
API 程 序 动 驱<br />
种 基 于 句 柄 、 命 令 式 的 API: 一<br />
多 数 对 象 都 通 过 不 透 明 的 句 柄 引 用 , 此 类 句 柄 可 指 定<br />
表 4-1<br />
<strong>CUDA</strong> 了 总<br />
用 的 对 象 。 可<br />
表 4-1.<br />
序 驱 动 程 序 API<br />
中 可 用 的 对 象<br />
CUdeviceptr 储 器 存 堆<br />
存 储 器 的 指 针 备<br />
<strong>CUDA</strong> 数<br />
描 设<br />
CUdevice 备 设<br />
持 <strong>CUDA</strong><br />
备 设<br />
4.5.3.1 初 始 化<br />
CUcontext 文 下 上<br />
CPU 同 于 等 致<br />
程<br />
CUmodule 块 模<br />
等 同 于 动 态 库 致<br />
CUfunction 数 函<br />
核<br />
4.5.3.2 设 备 管 理<br />
组 CUarray<br />
上 一 维 或 二 维 数 据 的 不 透 明 容 器 , 可 通 过 纹 理 参 考 读 取 备<br />
CUtexref 参 考 理 纹<br />
如 何 解 释 纹 理 存 储 器 数 据 的 对 象 述<br />
cuDeviceGetCount() 和<br />
提<br />
API 动 程 序 驱 在<br />
cuInit() 任 何 函 数 之 前 , 都 必 须 使 用 用 调<br />
初 始 化 。 行<br />
int deviceCount;<br />
cuDeviceGetCount(&deviceCount);<br />
int device;<br />
for (int device = 0; device < deviceCount; ++device) {<br />
CUdevice cuDevice;<br />
cuDeviceGet(&cuDevice, device);<br />
int major, minor;<br />
cuDeviceComputeCapability(&major, &minor, cuDevice);<br />
}<br />
: 性 属 其 索 检 便 以 ), 册<br />
cuDeviceGet()<br />
供 了 一 种 方 法 , 可 枚 举 这 些 设 备 和 其 他 功 能 ( 详 见 参 考 手<br />
4.5.3.3 上 下 文 管 理<br />
<strong>CUDA</strong> 上<br />
进<br />
中<br />
上<br />
在 该 上 下 文 被 销 毁 时 , 系 统 将 自 动 清 除 这 些 资 源 。 除 了 模 块 和 纹 理 参 考 之 类 的 对 象 之 外 , 每 个 上 下 文 还 有<br />
30 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程<br />
CPU 类 似 于 文 下<br />
API 在 驱 动 程 序 。 程<br />
<strong>CUDA</strong> 的 所 有 资 源 和 操 作 都 封 装 在 行 执<br />
下 文 内 ,<br />
32 独 有 的 己 自<br />
Cudeviceptr 空 间 。 因 而 , 不 同 上 下 文 的 址 地<br />
引 用 不 同 的 存 储 器 位 置 。 将
节<br />
函<br />
。cuCtxPopCurrent()<br />
上<br />
(usage<br />
库<br />
以<br />
创<br />
中<br />
或<br />
来<br />
(floating)”<br />
函<br />
输<br />
:<br />
用<br />
或<br />
cuCtxPopCurrent() 都 有 一 个 当 前 上 下 文 堆 栈 将 为 任 意 宿 主 线 程 的 当 前 上 下 文 压 入 个 每<br />
cuCtxDestroy() 使 将<br />
。cuCtxCreate() 将<br />
涉 及 设 备 模 拟 或 上 下 文 管 理 的 大 多 数 函 数 ) 将 返<br />
cuCtxDetach() 来<br />
此 外 还 会 为 每 个 上 下 文 维 护 一 个 使 用 计 数<br />
文 。cuCtxAttach()<br />
下 文 与 宿 主 线 程 分 离 开 来 。 随 后 此 上 下 文 将 成 为 “ 浮 动 还 可 恢 复 之 前 的 当 前 上 下 文 ( 如 果 存 在 )。 上<br />
count)。cuCtxCreate()<br />
则 将<br />
主 线 程 的 当 前 上 下 文 。 如 果 有 效 上 下 文 未 成 为 线 程 的 当 前 上 下 文 , 在 一 个 上 下 文 中 操 作<br />
cuCtxDetach() 用 计 数 递 增 , 而 使 使<br />
回 <strong>CUDA</strong>_ERROR_INVALID_CONTEXT。<br />
使 之 递 减 。 在 调<br />
通 过 使 用 计<br />
上 下 文 压 入 堆 栈 顶 端 。 可 调 上 下 文 , 可 作 创 新<br />
的 <strong>CUDA</strong><br />
数 1<br />
数 ( 不<br />
建 一 个 上 下<br />
cuCtxCreate() 宿 主 线 程 一 次 只 能 有 一 个 当 前 设 备 上 下 文 。 在 使 用 个 一<br />
建 上 下 文 时 , 它 将 成 为 调 用 方 宿<br />
用 cuCtxDetach()<br />
使 用 计 数<br />
时<br />
客<br />
为 0<br />
用 相 同 的 上 下 文 , 则 每 个 库 都 将 调<br />
上 下 文 将 被 销 毁 。 ,<br />
用 计 数 促 进 了 在 同 一 上 下 文 中 操 作 第 三 授 权 代 码 之 间 的 互 操 作 。 举 例 来 说 , 如 果 载 入 了 三 个 库 使 递 减 使 用 计 数 。 对 于 大 多 数 来 说 , 应 用 程 序 将 在 载 入 或 初 始 化 库 之 前 创 建 一 个 上 下 文 , 通 过 这 种 方 式 , 应 用 程 序 即 可 使 用 自 己 的 启 发 式 方 法 来 创 建 上 下 文 , 库 只 需 在 传 递 给 它 的 上 下 文 中 操 作 即 可 。 使<br />
用 cuCtxAttach()<br />
来<br />
和<br />
如<br />
所<br />
递 增 使 用 计 数 , 并 在 库 不 再 使 用 该 上 下 文 时 调<br />
用<br />
希 望 创 建 自 己 的 上 下 文 的 库 (<br />
其 API<br />
户 端 并 不 了 解 这 种 情 况 , 并 且 可 能 已 经 创 建 或 未 创 建 自 己 的 上 下<br />
cuCtxPushCurrent() 可 使 用 ) 文<br />
cuCtxPopCurrent(),<br />
图 4-1<br />
。 示<br />
4.5.3.4 模 块 管 理<br />
图 4-1.<br />
库 上 下 文 管 理<br />
是<br />
CUmodule cuModule;<br />
cuModuleLoad(&cuModule, “myModule.cubin”);<br />
CUfunction cuFunction;<br />
作<br />
cuModuleGetFunction(&cuFunction, cuModule, “myKernel”);<br />
面 的 代 码 示 例 载 入 了 一 个 模 块 并 检 索 内 核 的 句 柄 : 下 。 操 互 行 进 中 文 下<br />
(module)<br />
4.5.3.5 执 行 控 制<br />
是<br />
参 见 第 4.2.5<br />
)。 所 有 符 号 的 名 称 ( 包 括 函 数 、 全 局 变 量 和 纹 理 参 考 ) 均 在 模 块 范 围 内 维 护 , 从 而 使 独<br />
模 块<br />
Windows 态 加 载 的 设 备 代 码 和 数 据 包 , 类 似 于 动 可<br />
的 DLL,<br />
由 nvcc<br />
出 的 ( 请<br />
cuFuncSetBlockShape() 为<br />
分 配 方 式 。 的<br />
<strong>CUDA</strong> 编<br />
31<br />
的 第 二 个 参 数 指 定 参 数 在 参 数 堆 栈 中 的 偏 移 。 这 个 偏 移 量 必 须 与 参 数 一 种 可 迁 移 的 方 式 来 完 成 此 任 务 数<br />
<strong>CUDA</strong> 第 三 方 编 写 的 模 块 可 在 相 同 的 的 立<br />
cuFuncSetSharedSize() 为<br />
cuParam*() 系<br />
数 设 置 共 享 存 储 器 的 大 小 。 函<br />
cuFuncSetBlockShape(cuFunction, blockWidth, blockHeight, 1);<br />
__alignof()<br />
参 数 。 类 型 的 对 齐 要 求 相 匹 配 。 可 通 过 使 用 的 供<br />
2.0 南 , 版 本 指 程<br />
threadID 函 数 设 置 每 个 块 的 线 程 数 , 同 时 还 会 设 置 其 定 给<br />
cuLaunch()<br />
各 cuParam*()<br />
cuLaunchGrid() 数 用 于 指 定 在 下 一 次 调 用 函 列<br />
启 动 内 核 时 为 内 核 提
中<br />
的<br />
个<br />
、cuMemAllocPitch() 分<br />
线 性 存 储 器 。 放<br />
节<br />
、<strong>CUDA</strong><br />
数<br />
int offset = 0;<br />
int i;<br />
cuParamSeti(cuFunction, offset, i);<br />
offset += sizeof(i);<br />
float f;<br />
cuParamSetf(cuFunction, offset, f);<br />
offset += sizeof(f);<br />
char data[32];<br />
cuParamSetv(cuFunction, offset, (void*)data, sizeof(data));<br />
offset += sizeof(data);<br />
cuParamSetSize(cuFunction, offset);<br />
cuFuncSetSharedSize(cuFunction, numElements * sizeof(float));<br />
cuLaunchGrid(cuFunction, gridWidth, gridHeight);<br />
4.5.3.6 存 储 器 管 理<br />
或<br />
分<br />
释<br />
CUdeviceptr devPtr;<br />
cuMemAlloc(&devPtr, 256 * sizeof(float));<br />
:<br />
// host code<br />
CUdeviceptr devPtr;<br />
int pitch;<br />
cuMemAllocPitch(&devPtr, &pitch,<br />
因<br />
浮 点 元 素 的 数 组<br />
width * sizeof(float), height, 4);<br />
cuModuleGetFunction(&cuFunction, cuModule, “myKernel”);<br />
cuFuncSetBlockShape(cuFunction, 512, 1, 1);<br />
cuParamSeti(cuFunction, 0, devPtr);<br />
cuParamSetSize(cuFunction, sizeof(devPtr));<br />
cuLaunchGrid(cuFunction, 100, 1);<br />
// device code<br />
__global__ void myKernel(float* devPtr)<br />
{<br />
for (int r = 0; r < height; ++r) {<br />
float* row = (float*)((char*)devPtr + r * pitch);<br />
for (int c = 0; c < width; ++c) {<br />
float element = row[c];<br />
}<br />
}<br />
}<br />
<strong>CUDA</strong> 数<br />
创<br />
销<br />
cuMemAlloc() 用 使 可<br />
cuMemAllocPitch()<br />
cuMemFree() 性 存 储 器 , 并 使 用 线 配<br />
256 的 代 码 示 例 在 线 性 存 储 器 中 分 配 了 一 个 包 含 面 下<br />
建 议 在 分 配 二 维 数 组 时 使<br />
用 cudaMallocPitch(),<br />
5.1.2.1 能 确 保 合 理 填 充 已 分 配 的 存 储 器 , 满 足 第 它 为<br />
绍 的 对 齐 要 求 , 从 而 确 保 访 问 行 地 址 或 执 行 二 维 数 组 与 设 备 存 储 器 的 其 他 区 域 之 间 的 复 制 ( 使 用<br />
cudaMemcpy2D()) 时 获 得 最 优 性 能 。 所 返 回 的 间 距 ( 或 步 幅 ) 必 须 用 于 访 问 数 组 元 素 。 以 下 代 码 示 例 将 分 介<br />
widthxheight 个 一 配<br />
维 浮 点 值 数 组 , 并 显 示 如 何 在 设 备 代 码 中 循 环 遍 历 数 组 元 素 : 二<br />
。 毁<br />
的<br />
数<br />
位<br />
浮 点 组 件 : 的<br />
<strong>CUDA</strong>_ARRAY_DESCRIPTOR desc;<br />
desc.Format = CU_AD_FORMAT_FLOAT;<br />
desc.NumChannels = 1;<br />
desc.Width = width;<br />
desc.Height = height;<br />
CUarray cuArray;<br />
cuArrayCreate(&cuArray, &desc);<br />
分<br />
组<br />
32 <strong>CUDA</strong> 编<br />
cuArrayCreate() 使 用 是 组<br />
cuArrayDestroy() , 使 用 的 建<br />
配 的 线 性 存 储 器<br />
widthxheight 代 码 示 例 分 配 了 一 个 下 以<br />
<strong>CUDA</strong><br />
32 包 含 一 个 , 组<br />
<strong>CUDA</strong>_MEMCPY2D copyParam;<br />
memset(©Param, 0, sizeof(copyParam));<br />
存 储 器 : 性 线 的 配<br />
copyParam.dstMemoryType = CU_MEMORYTYPE_ARRAY;<br />
copyParam.dstArray = cuArray;<br />
copyParam.srcMemoryType = CU_MEMORYTYPE_DEVICE;<br />
cuMemAlloc() 手 册 列 举 了 用 于 在 考 参<br />
2.0 南 , 版 本 指 程<br />
<strong>CUDA</strong> 之 间 复 制 存 储 器 的 所 有 函 数 。 下 面 的 代 码 示 例 将 二 维 数 组 复 制 到 之 前 代 码 示 例 中 分 配 的 组 数
。hostPtr<br />
copyParam.srcDevice = devPtr;<br />
copyParam.srcPitch = pitch;<br />
copyParam.WidthInBytes = width * sizeof(float);<br />
copyParam.Height = height;<br />
cuMemcpy2D(©Param);<br />
float data[256];<br />
int size = sizeof(data);<br />
CUdeviceptr devPtr;<br />
cuMemAlloc(&devPtr, size);<br />
cuMemcpyHtoD(devPtr, data, size);<br />
4.5.3.7 流 管 理<br />
面 的 代 码 示 例 将 一 些 宿 主 存 储 器 数 组 复 制 到 设 备 存 储 器 中 : 下<br />
CUstream stream[2];<br />
for (int i = 0; i < 2; ++i)<br />
cuStreamCreate(&stream[i], 0);<br />
for (int i = 0; i < 2; ++i)<br />
cuMemcpyHtoDAsync(inputDevPtr + i * size, hostPtr + i * size,<br />
size, stream[i]);<br />
for (int i = 0; i < 2; ++i) {<br />
cuFuncSetBlockShape(cuFunction, 512, 1, 1);<br />
int offset = 0;<br />
cuParamSeti(cuFunction, offset, outputDevPtr);<br />
offset += sizeof(int);<br />
cuParamSeti(cuFunction, offset, inputDevPtr);<br />
offset += sizeof(int);<br />
cuParamSeti(cuFunction, offset, size);<br />
offset += sizeof(int);<br />
cuParamSetSize(cuFunction, offset);<br />
cuLaunchGridAsync(cuFunction, 100, 1, stream[i]);<br />
面 的 代 码 示 例 创 建 了 两 个 流 : 这 些 流 均 通 过 以 下 代 码 示 例 定 义 为 一 个 任 务 序 列 , 包 括 一 次 从 宿 主 到 设 备 的 存 储 器 复 制 、 一 次 内 核 启 动 、 下<br />
次 从 设 备 到 宿 主 的 存 储 器 复 制 : 一<br />
}<br />
for (int i = 0; i < 2; ++i)<br />
cuMemcpyDtoHAsync(hostPtr + i * size, outputDevPtr + i * size,<br />
size, stream[i]);<br />
cudaCtxSynchronize();<br />
的<br />
数<br />
cuFunction<br />
允 处<br />
复<br />
必 的<br />
处 理 hostPtr<br />
许 一 个 流 的 存 储 器 复 制 与 另 外 一 个 流 的 内 核 执 行 相 互 重 叠<br />
须 指 向 分 页 锁 定 的 宿<br />
float* hostPtr;<br />
器 , 这 样 才 能 同 时 执 行 : 储 存 主<br />
cuMemAllocHost((void**)&hostPtr, 2 * size);<br />
hostPtr 流 均 会 将 其 输 入 数 组 个 两<br />
inputDevPtr 分 复 制 到 设 备 存 储 器 中 的 部 一<br />
中 , 通 过 调 用 组<br />
并<br />
设 备 上 的 inputDevPtr, 理<br />
outputDevPtr 果 结 将<br />
hostPtr 回 制<br />
相 同 部 分 。 使 用 两 个 流<br />
cuStreamSynchronize() 可<br />
4.5.3.8 事 件 管 理<br />
目<br />
事 件 管 理<br />
CUevent start, stop;<br />
cuEventCreate(&start);<br />
cuEventCreate(&stop);<br />
后 调 用 的 是 在 进 一 步 处 理 之 前 确 定 所 有 流 均 已 完 成 。 用 于 同 步 宿 主 与 特 定 流 , 允 许 其 他 流 继 续 在 该 设 备 上 执 行 。 最<br />
面 的 代 码 示 例 创 建 了 两 个 事 件 : 下<br />
<strong>CUDA</strong> 编<br />
33<br />
了 cuCtxSynchronize(),<br />
cuEventRecord(start, 0);<br />
for (int i = 0; i < 2; ++i)<br />
cuMemcpyHtoDAsync(inputDevPtr + i * size, hostPtr + i * size,<br />
些 事 件 可 用 于 为 上 一 节 的 代 码 示 例 计 时 , 方 法 如 下 : 这<br />
2.0 南 , 版 本 指 程
注 册 。 消<br />
包<br />
初<br />
的<br />
返<br />
或<br />
size, stream[i]);<br />
for (int i = 0; i < 2; ++i) {<br />
cuFuncSetBlockShape(cuFunction, 512, 1, 1);<br />
int offset = 0;<br />
cuParamSeti(cuFunction, offset, outputDevPtr);<br />
offset += sizeof(outputDevPtr);<br />
cuParamSeti(cuFunction, offset, inputDevPtr);<br />
offset += sizeof(inputDevPtr);<br />
cuParamSeti(cuFunction, offset, size);<br />
offset += sizeof(size);<br />
cuParamSetSize(cuFunction, offset);<br />
cuLaunchGridAsync(cuFunction, 100, 1, stream[i]);<br />
}<br />
for (int i = 0; i < 2; ++i)<br />
cuMemcpyDtoHAsync(hostPtr + i * size, outputDevPtr + i * size,<br />
size, stream[i]);<br />
cuEventRecord(stop, 0);<br />
cuEventSynchronize(stop);<br />
float elapsedTime;<br />
cuEventElapsedTime(&elapsedTime, start, stop);<br />
cuEventDestroy(start);<br />
cuEventDestroy(stop);<br />
4.5.3.9 纹 理 参 考 管 理<br />
cuTexRefSetArray() 将<br />
texture texRef;<br />
的<br />
CUtexref cuTexRef;<br />
cuModuleGetTexRef(&cuTexRef, cuModule, “texRef”);<br />
指 绑<br />
cuTexRefSetAddress() 核 使 用 纹 理 参 考 从 纹 理 存 储 器 中 读 取 之 前 , 必 须 使 用 内 在<br />
理 参 考 绑 定 到 纹 理 。 纹<br />
块 cuModule<br />
定 义 如 下 的 纹 理 参 考 texRef: 含<br />
如 果 模<br />
cuTexRefSetAddress(NULL, cuTexRef, devPtr, size);<br />
数 绑<br />
texRef 面 的 代 码 示 例 将 检 索 下 则<br />
柄 : 句<br />
cuTexRefSetArray(cuTexRef, cuArray, CU_TRSA_OVERRIDE_FORMAT);<br />
4.5.3.10 OpenGL 互 操 作 性<br />
texRef 的 代 码 示 例 将 面 下<br />
devPtr 到 定<br />
的 线 性 存 储 器 : 向<br />
texRef 的 代 码 示 例 将 面 下<br />
<strong>CUDA</strong> 到 定<br />
组 cuArray:<br />
考 手 册 列 举 了 用 于 设 置 寻 址 模 式 、 过 滤 模 式 和 其 他 针 对 纹 理 参 考 的 标 记 的 各 种 函 数 。 在 将 纹 理 绑 定 到 纹 理 参 考 时 所 指 定 的 格 式 必 须 与 声 明 纹 理 参 考 时 指 定 的 参 数 相 匹 配 ; 否 则 纹 理 拾 取 的 结 果 将 无 法 确 定 。 参<br />
GLuint bufferObj;<br />
cuGLRegisterBufferObject(bufferObj);<br />
GLuint bufferObj;<br />
CUdeviceptr devPtr;<br />
int size;<br />
cuGLMapBufferObject(&devPtr, &size, bufferObj);<br />
成 : 完<br />
除 映 射 是 通 解<br />
操 作 性 。 之 互<br />
完<br />
的 设 备 存 储 器 地 址 读 取 或 写 入 缓 冲 对 象 : 回<br />
取<br />
34 <strong>CUDA</strong> 编<br />
cuGLInit() 使 用 须 必<br />
OpenGL 与 化 始<br />
先 必 须 将 一 个 缓 冲 对 象 注 册 到 <strong>CUDA</strong>, 首<br />
cuGLRegisterBufferObject() 能 进 行 映 射 。 可 通 过 才 后<br />
cuGLMapBufferObject() 完 成 后 , 内 核 即 可 使 用 册 注<br />
cuGLUnregisterBufferObject() , 可 使 用 的 成<br />
2.0 南 , 版 本 指 程<br />
过 cuGLUnmapBufferObject()
创<br />
填<br />
程 指 南 , 版<br />
上 上<br />
将<br />
资<br />
设<br />
用<br />
为<br />
4.5.3.11 Direct3D 互 操 作 性<br />
Direct3D 互<br />
LPDIRECT3DVERTEXBUFFER9 buffer;<br />
cuD3D9RegisterResource(buffer, CU_D3D9_REGISTER_FLAGS_NONE);<br />
LPDIRECT3DSURFACE9 surface;<br />
cuD3D9RegisterResource(surface, CU_D3D9_REGISTER_FLAGS_NONE);<br />
cuD3D9RegisterResource()<br />
cuD3D9UnregisterVertexBuffer() 可 可<br />
<strong>CUDA</strong> 性 要 求 在 创 建 作 操<br />
Direct3D 时 指 定 文 下<br />
cuD3D9CtxCreate() 通 过 使 用 。 备<br />
cuCtxCreate() 非 而<br />
建 <strong>CUDA</strong><br />
下 文 即 可 实 现 此 目 标 。。<br />
cuD3D9UnmapResources()<br />
有 较 高 的 开 销 , 通 常 仅 为 每 个 资 源 调 用 一 次 。 使 取 消 注 册 。 之 和 任 意 多 次 地 映 射 和 解 除 映 射 。 内 核 可 使 用 具 能<br />
cuD3D9ResourceGetMappedPointer()<br />
cuD3D9ResourceGetMappedSize()、cuD3D9ResourceGetMappedPitch()<br />
cuD3D9ResourceGetMappedPitchSlice() 返 访 及 返<br />
cuD3D9RegisterResource() 即 可 使 用 后 随<br />
Direct3D<br />
注 册 到 <strong>CUDA</strong>: 源<br />
0<br />
CUdeviceptr devPtr;<br />
cuD3D9ResourceGetMappedPointer(&devPtr, buffer);<br />
size_t size;<br />
cuD3D9ResourceGetMappedSize(&size, buffer);<br />
cuMemset(devPtr, 0, size);<br />
用<br />
height) 的<br />
设 备 存 储 器 地 址 和 回 的 大 小 和 间 距 信 息 来 读 取 和 写 入 已 映 射 的 资 源 。 通 问 已 映 射 的 资 源 将 导 致 不 确 定 的 结 果 。 回<br />
面 的 代 码 示 例 使 充 了 一 个 缓 冲 区 : 下<br />
<strong>CUDA</strong> 源 注 册 到 资 将<br />
cuD3D9MapResources() 即 可 在 需 要 时 分 别 使 用 , 后<br />
// host code<br />
代 码 示 例 中 , 每 个 线 程 都 访 问 大 小 的 面 下 在<br />
CUdeviceptr devPtr;<br />
cuD3D9ResourceGetMappedPointer(&devPtr, surface);<br />
size_t pitch;<br />
cuD3D9ResourceGetMappedPitch(&pitch, surface);<br />
cuModuleGetFunction(&cuFunction, cuModule, “myKernel”);<br />
cuFuncSetBlockShape(cuFunction, 16, 16, 1);<br />
int offset = 0;<br />
cuParamSeti(cuFunction, offset, devPtr);<br />
offset += sizeof(devPtr);<br />
cuParamSeti(cuFunction, 0, width);<br />
offset += sizeof(width);<br />
cuParamSeti(cuFunction, 0, height);<br />
offset += sizeof(height);<br />
cuParamSeti(cuFunction, 0, pitch);<br />
offset += sizeof(pitch);<br />
cuParamSetSize(cuFunction, offset);<br />
cuLaunchGrid(cuFunction,<br />
(width+Db.x–1)/Db.x, (height+Db.y–1)/Db.y);<br />
// device code<br />
__global__ void myKernel(unsigned char* surface,<br />
int width, int height, size_t pitch)<br />
{<br />
int x = blockIdx.x * blockDim.x + threadIdx.x;<br />
int y = blockIdx.y * blockDim.y + threadIdx.y;<br />
if (x >= width || y >= height) return;<br />
float* pixel = (float*)(surface + y * pitch) + 4 * x;<br />
}<br />
二 维 表 面 的 一 个 像 素 , 像 素 格 式<br />
过 Direct3D<br />
为 (width,<br />
float4:<br />
<strong>CUDA</strong> 编<br />
35<br />
本 2.0
,(i/n) 等<br />
和<br />
块<br />
块<br />
位 个<br />
个<br />
。<br />
而<br />
;:<br />
节<br />
、__logf(x)(<br />
等<br />
(arithmetic<br />
和<br />
节<br />
,__[u]mul24 将<br />
个<br />
位 位<br />
是<br />
个<br />
个<br />
第 5 章 性 能 指 南<br />
5.1 指 令 性 能<br />
<br />
<br />
<br />
执 读<br />
行 指 令 ; 块<br />
为<br />
块<br />
理 指 令 , 多 处 理 器 必 须 中 各 线 程 的 指 令 操 作 数 处<br />
中 各 线 程 写 入 结 果<br />
最 量<br />
<br />
允 最<br />
warp<br />
<br />
节<br />
intensity), 也<br />
warp 线 程 为 要<br />
许 线 程 调 度 程 序 尽 可 能 地 同 时 进 行 存 储 器 事 务 处 理 与 数 学 计 算 , 这 要 求<br />
取 warp<br />
而 , 有 效 的 指 令 吞 吐 量 取 决 于 额 定 指 令 吞 吐 量 以 及 存 储 器 延 迟 和 带 宽 。 可 通 过 以 下 方 法 最 大 化 指 令 吞 吐<br />
<br />
因<br />
每<br />
5.1.1 指 令 吞 吐 量<br />
小 化 吞 吐 量 较 低 的 指 令 的 使 用 ( 参 见 :<br />
);<br />
5.1.1<br />
线 程 执 行 的 程 序 具 有 较 高 的 运 算 强 度 第<br />
数 学 操 作 ; 量<br />
5.1.1.1 数 学 指 令<br />
就 是 说 , 让 每 个 存 储 器 操 作 对 应 大 :<br />
5.1.2 用 于 每 一 类 存 储 器 的 可 用 存 储 器 带 宽 的 使 用 ( 参 见 第 化 大<br />
);<br />
4<br />
<br />
<br />
<br />
16<br />
位 32<br />
单 整 位 个<br />
加<br />
节<br />
5.2 处 理 器 上 具 有 多 个 活 动 线 程 , 如 第 多 个<br />
述 。 所<br />
钟 周 期 , 用 于 : 型 加 法 ; 运 算 、 比 较 、 最 小 值 、 最 大 值 、 类 型 转 换 指 令 ; 时<br />
供 有 符 号 和 无 符 号 24<br />
整 型 乘 法 。 而 在 未 来 的 架 构 中<br />
型 乘 法 的 速 度 更 慢 , 因 整 型 乘 法 , 由 应 用 程 序 合 理 整<br />
warp 一 个 为 要<br />
出 一 条 指 令 , 多 处 理 器 需 占 用 : 发<br />
- 浮 点 加 法 、 乘 法 和 乘 度 精<br />
;<br />
另<br />
是<br />
的<br />
)。 请 参 见 附 录 B) 可 请<br />
时 钟 周 期 内 提<br />
这 些 转 换 。<br />
36 <strong>CUDA</strong> 编<br />
时 钟 周 期 ,<br />
时 钟 周 期 , 用 于 倒 数 、 平 方 根 倒 数<br />
B.2 第 见 参<br />
。<br />
16 乘 法 占 用 型 整<br />
但 __mul24<br />
__umul24(<br />
2<br />
在 4<br />
y) 提 块<br />
比 32<br />
我 们 建 议 您 设 计 两 套 内 核 , 一 个 使 用 __[u]mul24, 此<br />
32 使 用 普 通 的 个 一<br />
__sinf(x)、__cosf(x)、__expf(x) 占 B)。 录<br />
个<br />
。sinf(x)、cosf(x)、tanf(x)、sincosf(x)<br />
用 整 型 除 法 和 求 模 运 算 的 成 本 极 高 , 应 尽 可 能 避 免 使 用 , 或 在 可 能 的 情 况 下 替 换 为 位 运 算 : 如 如 调<br />
果 n<br />
他 函 数 要 占 用 更 多 的 时 钟 周 期 , 因 为 它 们 是 作 为 多 种 指 令 的 混 合 体 实 现 的 。 单 精 度 浮 点 平 方 根 是 作 为 倒 数 平 方 根 再 求 倒 数 实 现 的 , 而 非 先 求 倒 数 平 方 根 再 求 乘 积 , 因 为 只 有 这 样 才 能 其<br />
期 ( 请 参 见 附 周<br />
于 (i>>log2(n)), 价<br />
(i%n)<br />
于 (i&(n-1)); 价<br />
果 n<br />
常 量 , 则 编 译 器 将 执 行<br />
幂<br />
36 度 浮 点 除 法 要 占 用 精 单<br />
__fdividef(x, 周 期 , 但 钟 时<br />
20 速 度 更 快 的 版 本 , 只 需 占 用 了 供<br />
时 钟<br />
2.0 南 , 版 本 指 程<br />
为 0<br />
warp 大 给 出 正 确 结 果 。 因 而 , 一 个 穷 无<br />
32 用 占 将<br />
钟 周 期 。 时<br />
用 32<br />
时 钟 周 期
块<br />
器 延 迟 。<br />
的<br />
(if、switch、do、for、while)<br />
的<br />
为<br />
块<br />
块<br />
谓<br />
了<br />
、4<br />
块<br />
是<br />
节<br />
块<br />
块<br />
果 x<br />
对 值 大 于 48039( 绝<br />
见 math_functions.h<br />
5.1.2.2 低 性 能 , 因 为 本 地 存 储 器 的 延 迟 较 高 , 也 存 在 带 宽 问 题 ( 请 参 见 第 降 步<br />
)。<br />
<br />
<br />
单 节 可 通 过 以 下 方 法 避 免 上 述 的 后 两 种 情 况 : 双<br />
成 本 更 高 , 如 参 解 更 多 细 节 ), 则 成 本 还 要 更 高 ( 也 就 是 说 , 速 度 降 低 约 一 个 数 量 级 )。 此 外 , 在 这 种 情 况 下 , 参 数 约 减 代 码 使 用 本 地 存 储 器 , 这 可 能 会 进 一 有 些 时 候 , 编 译 器 必 须 插 入 转 换 指 令 , 这 又 带 来 了 额 外 的 执 行 周 期 。 可 能 导 致 此 类 情 况 的 条 件 包 括 : 的<br />
类 精 度 浮 点 常 量 ( 定 义 时 不 带 任 何 类 型 后 缀 ) 用 作 单 精 度 浮 点 计 算 的 输 入 ; 或<br />
<br />
<br />
5.1.1.2 控 制 流 指 令<br />
力 能 算 计 如<br />
后 类 或 更 低 的 设 备 , 应 将 双 精 度 算 法 替 换 为 单 精 度 算 法 。 后<br />
控 制 流 指 令<br />
对 char<br />
short<br />
进 行 操 作 的 函 数 , 其 操 作 数 通 常 需 要 转 换 为 int; 型<br />
B.1.2 浮 点 变 量 用 作 度 精<br />
定 义 的 数 学 函 数 的 双 精 度 版 本 的 输 入 参 数 。 所<br />
的 线 程 分 支 , 从 而 显 著 影 响 有 效 的<br />
型 和 单 精 度 数 学 函 数 。 在 为 不 具 备 本 地 双 精 度 支 持 的 设 备 编 译 时 ,<br />
f 单 精 度 浮 点 常 量 , 在 定 义 时 带 用 使<br />
, 如 3.141592653589793f、1.0f、0.5f; 缀<br />
/ WSIZE) 时 块 块<br />
节<br />
f 数 学 函 数 的 单 精 度 版 本 , 定 义 时 同 样 带 用 使<br />
, 如 sinf()、logf()、expf()。 缀<br />
float 单 精 度 代 码 , 强 烈 建 议 使 用 于 对<br />
为 1.2<br />
任 何 流 控 制 指 令<br />
warp 致 同 一 导 会<br />
节<br />
块<br />
(branch<br />
unroll<br />
或 语 指 来 predication)<br />
令 吞 吐 量 , 也 就 是 说 , 这 些 指 令 会 导 致 线 程 采 用 不 同 的 执 行 路 径 。 如 果 出 现 这 种 情 况 , 就 必 须 序 列 化<br />
(serialize) 不 将 重 新 汇 聚 到 同 一 执 行 路 径 。 指<br />
warp 执 行 路 径 , 因 而 增 加 了 该 的 同<br />
执 行 的 指 令 总 数 。 完 成 所 有 不 同 的 执 行 路 径 时 , 线 程<br />
都<br />
ID 在 控 制 流 以 线 程 了 为<br />
warp 的 情 况 下 获 得 最 佳 性 能 , 应 编 写 控 制 条 件 , 最 小 化 分 支 据 依<br />
的 数 量 。<br />
warp 完 全 可 行 的 , 因 为 是 这<br />
3.1 内 的 分 布 情 况 是 确 定 的 , 如 块 在<br />
所 述 。 以 一 个 简 单 的 情 况 为 例 , 当<br />
或<br />
的<br />
(threadIdx 条 件 仅 依 赖 于 制 控<br />
WSIZE 如 此 , 其 中 的 是 就<br />
warp<br />
的 大 小 。 此 时 不 会 出 现 任<br />
在 使 用 转 移 猜 测 时 , 依 靠 控 制 条 件 执 行 的 任 何 指 令 都 不 会 被 跳 过 。 而 是 分 别 与 一 个 每 线 程 条 件 代 码 或 根 据<br />
何 warp<br />
warp , 因 为 控 制 条 件 与 支 分<br />
美 对 齐 。 完<br />
相 (predicate)<br />
5.1.1.3 存 储 器 指 令<br />
有 些 时 候 , 控 制 器 可 能 会 展 开 循 环 , 或 通 过 使 用 转 移 猜 测<br />
if 化 优<br />
switch<br />
句 ,<br />
warp 将 加 以 介 绍 。 在 这 些 情 况 下 , 不 会 有 任 何 文 下<br />
#pragma 。 程 序 员 还 可 使 用 支 分<br />
令 控 制 循<br />
4.2.5.2 展 开 ( 请 参 见 第 的 环<br />
)。<br />
warp<br />
。 只 有 在 分 支 条 件 控 制 的 指 令 数 量 小 于 或 等 于 特 定 阈 值 时 , 编 译 器 才 会 使 用 猜 测 的 指 令 替 换 分 支 指 令 : 如 果 编 译 确 定 出 有 可 能 产 生 大 量 分 支 的 条 件 , 则 此 阈 值 为 7, 否 则 为 4。 作 数<br />
器 指 令 包 含 读 取 或 写 入 共 享 、 本 地 或 全 局 存 储 器 的 任 何 指 令 。 只 有 在 使 用 某 些 自 动 变 量 时 才 会 发 生 本 节 储 存<br />
到<br />
个<br />
个<br />
块<br />
true 条 件 设 置 为 制 控<br />
false<br />
谓 词<br />
关 联 , 尽 管 每 一 条 指 令 都 为 执 行 而 进 行 了 调 度 , 但 只<br />
true 词 为 谓 有<br />
false 才 会 被 实 际 执 行 。 带 有 令 指<br />
词 的 指 令 不 会 写 入 结 果 , 也 不 会 计 算 地 址 或 读 取 操<br />
__shared__ float shared[32];<br />
__device__ float device[32];<br />
shared[threadIdx.x] = device[threadIdx.x];<br />
个 个<br />
到<br />
个<br />
<strong>CUDA</strong> 编<br />
37<br />
果 在 等 待 全 局 存 储 器 访 问 完 成 时 有 足 够 的 独 立 算 数 指 令 可 发 出 , 则 线 程 调 度 程 序 可 隐 藏 这 样 的 全 局 存 储 如<br />
例 说 明 , 注 意 以 下 示 例 代 码 中 的 赋 值 运 算 符 : 举<br />
4.2.2.4 储 器 访 问 , 详 见 第 存 地<br />
。<br />
4 理 器 要 占 用 处 多<br />
warp 周 期 来 为 一 个 钟 时<br />
发 出 一 条 存 储 器 指 令 。 在 访 问 本 地 或 全 局 存 储 器 时 , 还<br />
400 额 外 的 在 存<br />
600<br />
钟 周 期 的 存 储 器 延 迟 。 时<br />
4 占 用 将 它<br />
时 钟 周 期 来 发 送 全 局 存 储 器 的 读 取 指 令<br />
时 钟 周 期 来 发 送 共 享 存 储 器 的 写 入 指 令 , 但<br />
2.0 南 , 版 本 指 程<br />
400 需 要 共 总<br />
600<br />
钟 周 期 来 从 全 局 存 储 器 读 取 一 个 浮 点 数 。 时
个<br />
,type<br />
位<br />
、64 位<br />
个<br />
或<br />
条<br />
位<br />
的<br />
位<br />
块<br />
出 指 令 。 发<br />
5.1.1.4 同 步 指 令<br />
,__syncthreads 将<br />
5.1.2 存 储 器 带 宽<br />
程 需 要 等 待 其 他 线 程 线 何 任 有 没 果 如<br />
存 储 器 带 宽<br />
<br />
<br />
<br />
<br />
<br />
若 在 与 将<br />
存 储 器 空 间 的 有 效 带 宽 主 要 取 决 于 访 问 模 式 下 面 几 节 将 介 绍 相 关 内 容 由 于 设 备 存 储 器 比 片 上 存 储 器 的 延 迟 更 高 、 带 宽 更 低 , 因 此 应 尽 量 减 少 设 备 存 储 器 访 问 。 典 型 的 编 程 模 式 是 将 来 自 设 备 存 储 器 的 数 据 转 入 共 享 存 储 器 , 也 就 是 说 , 使 一 个 块 的 所 有 线 程 各<br />
自 设 备 存 储 器 的 载 入 共 享 存 储 器 共 享 存 储 器 中 处 理 数 据 ; 来<br />
4 用 占<br />
warp 周 期 来 为 一 个 钟 时<br />
5.1.2.1 全 局 存 储 器<br />
:。<br />
块 中 的 其 他 所 有 线 程 同 步 , 使 各 线 程 可 安 全 地 读 取 由 其 他 线 程 写 入 的 共 享 存 储 器 位 置 ; 有 必 要 , 再 次 进 行 同 步 , 确 保 使 用 结 果 更 新 了 共 享 存 储 器 ; ;<br />
值 : 赋<br />
果 写 回 设 备 存 储 器 。 结<br />
__device__ type device[32];<br />
问 的 高 昂 成 本 时 更 是 如 此 。 访 器 储 存<br />
type data = device[tid];<br />
sizeof(type) 字 必<br />
的 等<br />
的<br />
全 局 存 储 器 空 间 不 会 被 缓 存 , 因 而 采 用 正 确 的 访 问 模 式 来 实 现 最 大 化 的 存 储 器 带 宽 尤 为 重 要 , 考 虑 到 设 备<br />
节<br />
或<br />
32 , 设 备 能 够 通 过 一 条 指 令 将 全 局 存 储 器 中 的 先 首<br />
或 128<br />
读 入 寄 存 器 。 对 于 下 面 这 样 的<br />
类<br />
或<br />
来<br />
struct __align__(8) {<br />
float a;<br />
float b;<br />
};<br />
对<br />
将 其 编 译 为 一 条 加 载 指 令<br />
sizeof(type) 使 须<br />
于 4、8<br />
16,<br />
type 为 型<br />
量 必 须 与 变<br />
sizeof(type) 致 ( 也 就 是 说 , 它 的 地 址 必 须 是 一 节<br />
倍 数 )。<br />
齐 要 求 , 举 例 如 下 :<br />
struct __align__(16) {<br />
对<br />
};<br />
float a;<br />
float b;<br />
float c;<br />
个<br />
4.3.1.1 于 对<br />
float2 的 内 置 类 型 , 如 绍 介<br />
float4,<br />
要 求 可 自 动 满 足 。 齐<br />
__align__(8) 结 构 体 来 说 , 可 通 过 使 用 对 齐 说 明 符 于 对<br />
__align__(16)<br />
使 编 译 器 实 施 大 小 和<br />
节 的 结 构 体 来 说 , 编 译 器 会 生 成 多 条 加 载 指 令 。 为 了 确 保 生 成 的 指 令 数 量 最 少 , 应 使 用 字<br />
__align__(16)<br />
struct __align__(16) {<br />
float a;<br />
float b;<br />
float c;<br />
float d;<br />
float e;<br />
};<br />
定<br />
: 或<br />
于 超 对<br />
条<br />
此 类 结 构 体 , 举 例 如 下 义<br />
位<br />
38 <strong>CUDA</strong> 编<br />
过 16<br />
加 载 指 令 , 而 的 加 载 指 令 。 位 于 全 局 存 储 器 中 的 变 量 的 地 址 , 或 由 驱 动 程 序 或 运 行 存 储 器 分 配 例 程 返 回 的 变 量 地 址 总 是 会 字 节 。<br />
:<br />
2 编 译 为 将 这<br />
非 5<br />
2.0 南 , 版 本 指 程<br />
256 到 至 少 齐 对<br />
时 API<br />
128<br />
32
warp , 当 半 块 中 的 线 程 同 时 进 行 的 存 储 器 访 问 ( 在 单 独 一 条 读 取 或 写 入 指 令 执 行 的 过 程 中 ) 可 合 并 一 个 存 储 器 事 务 , 全 局 存 储 器 带 宽 的 使 用 效 率 将 达 到 最 高 。 存 储 器 次 其<br />
(memory transaction)<br />
32 1.2 )、64 128<br />
warp<br />
大 小 可 为 字 节 ( 仅 针 对 为 或 更 高 设 备 位 或 位 本 节 的 后 续 内 容 将 介 绍 根 据 设 备 的 计 算 能 力 合 并 存 储 器 访 问 的 各 种 需 求 。 如 果 半 务 事 时 (coalesce)<br />
warp<br />
能 够 满 足 这 些 需 求 , 即 便 在 块 分 支 、 块 的 某 些 线 程 并 未 实 际 访 问 存 储 器 的 情 况 下 , 也 可 实 现 合 并 。 。<br />
下 面 的 讨 论 中 , 全 局 存 储 器 将 被 视 为 分 区 成 大 小 等 或 字 节 的 部 分 , 并 且 对 齐 到 此 大 小 。 块 在<br />
warp<br />
warp<br />
半<br />
满 足 以 下 三 个 条 件 , 半 的 线 程 必 须 访 问 果 如<br />
在 计 算 能 力 为 1.0 和 1.1 的 设 备 上 进 行 存 储 器 合 并<br />
<br />
<br />
32、64 128 于<br />
32 64<br />
64 128<br />
128 128<br />
储 器 访 问 都 会 合 并 为 一 个 或 两 个 存 储 器 事 务 : 位 , 得 到 一 个 字 节 的 存 储 器 事 务 ,<br />
一 , 所 有<br />
16<br />
线<br />
128<br />
程 进 行 的 全 局 存<br />
存 储 器 事 务 ; 全 部 个 字 必 须 位 于 大 小 等 于 存 储 器 事 务 大 小 的 同 一 个 存 储 器 段 (segment) 中 ( 在 访 问 位 字 的 情 况 下 , 位 于 存 储 器 事 务 大 小 两 倍 的 分 段 中 ); 的 节 字 个 两 到 得 , 字 或 必 须 按 顺 序 访 问 字 : 块 中 的 个 线 程 必 须 访 问 个 字 。 如 果 块 不 满 足 上 述 所 有 需 求 , 将 为 各 线 程 发 出 一 个 独 立 的 存 储 器 事 务 , 而 吞 吐 量 将 显 著 降 低 。 显 示 了 接 合 后 的 存 储 器 访 问 的 示 例 , 而 和 显 示 了 未 为 计 算 能 力 或 的 设 备 进 行 存 储 器 合 并 的 存 储 器 访 问 示 例 。 程<br />
线<br />
warp k k<br />
warp<br />
5-1 5-2 5-3 1.0 1.1<br />
第<br />
64<br />
第<br />
32 128<br />
32 32<br />
64 4 ,128<br />
半<br />
2<br />
半<br />
的 位 访 问 带 宽 比 存 储 器 合 并 后 的 位 访 问 相 比 略 低 而 存 储 器 合 并 后 的 位 访 问 则 位 访 问 带 宽 低 出 许 多 。 然 而 , 同 为 位 访 存 时 , 尽 管 未 存 储 器 合 并 的 访 问 的 带 图 图 图 是<br />
器 合 并 后 的 访 问 带 宽 要 低 一 个 数 量 级 , 但 同 为 位 情 况 下 , 前 者 带 宽 比 后 者 低 倍 位 情 况 下 , 前 者 带 宽 比 后 者 低 倍 。 后 并 储 存 比 宽 合 器 储 存<br />
在 计 算 能 力 为 1.2 或 更 高 的 设 备 上 进 行 存 储 器 合 并<br />
warp 所 有 半 块 的 所 有 线 程 访 问 的 字 位 于 大 小 满 足 以 下 条 件 的 同 一 个 存 储 器 段 内 , 所 有 线 程 进 行 的 全 局 存 储 器 访 问 都 会 合 并 为 一 个 或 两 个 存 储 器 事 务 : 要 只<br />
<br />
<br />
如 块<br />
块<br />
位 字 8 32<br />
16 64<br />
32 64 128<br />
warp warp n n 字 , 则 为 节 ;<br />
n 1 16 128<br />
果 所 有 线 程 都 访 问 或 字 , 则 为 节 。 半 所 请 求 的 任 何 地 址 模 式 都 会 实 现 存 储 器 合 并 包 括 多 个 线 程 同 一 个 地 址 的 模 式 。 这 与 具 有<br />
能 力 的 设 备 的 情 况 截 然 不 同 , 在 那 种 情 况 下 , 线 程 需 要 串 行 地 访 问 字 。<br />
128 64<br />
如 果 半 在 不 同 的 存 储 器 段 内 对 字 进 行 寻 址 , 则 发 出 存 储 器 事 务 ( 每 个 事 务 针 对 一 个 存 储 器 段 ), 而 计 算 能 力 较 低 的 设 备 将 在 于 发 出 事 务 。 具 体 来 说 , 如 果 线 程 访 问 , 则 至 少 发 出 两 个 存 储 器 事 务 。<br />
warp<br />
较 低 计 算<br />
事 务 中 , 无 用 字 也 会 被 读 取 , 这 将 浪 费 带 宽 。 为 减 少 浪 费 , 硬 件 将 自 动 发 出 包 含 所 请 求 的 字 的<br />
8 32<br />
最 小 的 存 储 器 事 务 。 举 例 来 说 , 如 果 全 部 字 都 位 于 一 个 字 节 分 区 的 一 半 , 则 发 出 一 个 位<br />
16 64 32 、64 128 128<br />
的 事 务 。<br />
<br />
<br />
更 精 确 地 来 说 , 以 下 协 议 用 于 为 半 块 发 出 存 储 器 事 务 : 在<br />
<br />
存<br />
128<br />
储<br />
64<br />
器<br />
编 号 最 的 活 动 线 程 所 请 求 地 址 的 存 储 器 段 。 对 于 位 数 据 来 说 , 段 大 小 是 字 节 , 对 于 数 据 是 字 节 , 对 于 位 位 和 位 数 据 是 字 节 。<br />
<strong>CUDA</strong> 2.0 39<br />
求 位 于 同 一 存 储 器 段 内 的 地 址 的 其 他 所 有 活 动 线 程 。 尽 可 能 减 小 事 务 的 大 小 :<br />
包 含<br />
大 小 为 字 节 , 而 且 仅 使 用 了 下 半 或 上 半 , 则 将 事 务 大 小 缩 减 为 字 节 ; 务 事 果 如 请 找 查<br />
本 版 , 南 指 程 编<br />
个<br />
位<br />
大<br />
时<br />
字<br />
个<br />
个<br />
位
字<br />
存<br />
存<br />
或 块<br />
(inactive)。<br />
。<br />
。<br />
得 到 一 个 存 储 器 事 务 。<br />
存 储 器 合 并 后 的 存 储 器 访 问 模 式 示 例 。<br />
字<br />
。 节<br />
<br />
重<br />
如<br />
展<br />
64 务 大 小 为 事 果<br />
32 而 且 仅 使 用 了 下 半 或 上 半 , 则 将 事 务 大 小 缩 减 为 , 节<br />
执 行 事 务 , 并 将 得 到 服 务 的 线 程 标 记 为 不 活 动<br />
1.2 计 算 能 力 为 了 示<br />
更 高 的 设 备 的 全 局 存 储 器 访 问 示 例<br />
warp 述 操 作 , 直 至 为 半 上 复<br />
中 的 所 有 线 程 提 供 了 服 务<br />
图 5-4<br />
储 器 访 问 , 得 到 一 个 存 储 器 事 务<br />
40 <strong>CUDA</strong> 编<br />
float : 存 储 器 合 并 后 的 侧 左<br />
float : 存 储 器 合 并 后 的 侧 右<br />
器 访 问 ( 分 支 warp), 储<br />
图 5-1.<br />
2.0 南 , 版 本 指 程
存<br />
未 为 计<br />
程 指 南 , 版<br />
个<br />
个<br />
或<br />
务<br />
的 设 备 进 行 存 储 器 合 并 的 全 局 存 储 器 访 问 模 式 示 例 。<br />
储 器 事 务 存 储 器 事 存<br />
<strong>CUDA</strong> 编<br />
41<br />
float : 非 连 续 的 侧 左<br />
16 访 问 , 得 到 器 储<br />
16 : 使 用 未 对 齐 的 起 始 地 址 , 得 到 侧 右<br />
图 5-2.<br />
为 计 是 算 能 力 未<br />
是 1.0<br />
1.1<br />
本 2.0
存<br />
存<br />
未<br />
个<br />
或<br />
个<br />
。<br />
的 设 备 进 行 存 储 器 合 并 的 全 局 存 储 器 访 问 模 式 示 例<br />
存 储 器 事 务 42 <strong>CUDA</strong> 编<br />
float : 不 相 邻 的 侧 左<br />
16 访 问 , 得 到 器 储<br />
float3 : 不 相 邻 的 侧 右<br />
16 访 问 , 得 到 器 储<br />
图 5-3.<br />
是 未 为 计 算 能 力 是 1.0<br />
1.1<br />
2.0 南 , 版 本 指 程
字<br />
字<br />
存<br />
存<br />
,type<br />
计<br />
(Common<br />
南 , 版 指 程<br />
存<br />
或<br />
类<br />
为<br />
的<br />
。<br />
是<br />
节 的 存 储 器 段 内 的 随<br />
一 般 访 问 模 式<br />
间 右 侧 : 未 对 齐 中<br />
<strong>CUDA</strong> 编<br />
type*<br />
43<br />
组 存 储 于 存 储 器 之 中 , 而 不 是 单 独 一 个 型 的 数 组 。 数 个<br />
64 : 在 一 个 侧 左<br />
float<br />
Access<br />
机<br />
是 处<br />
Pattern)<br />
一 个 数 组 的 一 个 元 素 : 的<br />
每 个 线 程 使 用 以 下 地 址 访<br />
储 器 访 问 , 得 到 一 个 存 储 器 事 务<br />
的 float<br />
的 float<br />
图 5-4.<br />
为 计 算 能 力 为 1.2<br />
或 更 高 的 设 备 的 全 局 存 储 器 访 问 示 例<br />
BaseAddress + tid<br />
必<br />
器 访 问 , 得 到 一 个 事 务 。 储<br />
器 访 问 , 得 到 两 个 事 务 。 储<br />
局 存 储 器 的 一 般 访 问 模 式 全<br />
为 了 实 现 存 储 器 合 并<br />
须 满 足 上 文 介 绍 的 大 小 和 对 齐 要 求 。 具 体 来 说 , 这 也 就 意 味 着 , 如<br />
问 类 型 为 type*、<br />
位<br />
本 2.0<br />
ID 线 程 : 指<br />
tid<br />
BaseAddress 址 地 于<br />
果 type<br />
16 大 于 个 一<br />
节 的 结 构 体 , 就 应 将 其 分 割 为 多 个 满 足 这 些 需 求 的 结 构 体 , 而 数 据 应 作 为 此 类 结 构 体 的 多
(local<br />
(padding),<br />
块<br />
块<br />
是<br />
的<br />
块<br />
节<br />
个<br />
块<br />
:<br />
倍 个<br />
块<br />
的<br />
块<br />
(bank 访 conflict),<br />
(bank),<br />
址<br />
和<br />
块<br />
路<br />
BaseAddress 处<br />
的<br />
BaseAddress + width * ty + tx<br />
ty) 的<br />
<br />
Width<br />
线<br />
(tx, 一 种 全 局 存 储 器 一 般 访 问 模 式 是 索 引 为 外 另<br />
于 地<br />
cuMemAllocPitch() 函<br />
5.1.2.2 本 地 存 储 器<br />
维 数 组 中 的 一 个 元 素 大 小 的 倍 数 ; 二<br />
数 。<br />
么 对 于 该 数 组 的 访 问 就 越 有 效 率 。 参 考 手 册 中 介 绍 倍<br />
memory) 访<br />
应 的 填 充 那 数 和 相 关 的 存 储 器 复 制 函 数 使 程 序 员 能 够 编 写 不 依 赖 于 硬 件 的 代 码 , 以 分 配 符 合 这 些 限 制 条 件 的 数 组 。 相<br />
节<br />
实 现 存 储 器 合 并 : 位<br />
数 , 并 且 行 得 到 了 倍<br />
线 程 使 用 以 下 地 址 访 问 类 型 为 type*、 各<br />
width 度 为 宽 、<br />
warp 种 情 况 下 , 只 有 满 足 了 以 下 条 件 , 才 能 为 线 程 块 的 所 有 半 这 在<br />
warp 的 宽 度 是 半 块 程<br />
16<br />
16 来 说 , 这 也 就 意 味 着 , 宽 度 不 是 体 具<br />
16 的 数 组 在 分 配 时 的 宽 度 越 接 近 数 倍<br />
所 述 与 全 局 存 储 器 空 间 相 似 , 本 地 存 储 器 空 间 不 会 被 缓 存 , 因 此 本 地 存 储 器 的 访 问 成 本 与 全 局 存 储 器 一 样 高 。 但 由 于 它 们 在 定 义 上 是 基<br />
的 cudaMallocPitch()<br />
5.1.2.3 常 量 存 储 器<br />
4.2.2.4 由 某 些 自 动 变 量 分 配 , 如 第 仅 问<br />
每 个 线 程 的 , 因 而 访 问 总 是 会 合 并 。 于 存 储 器 空 间 会 被 缓 存 , 因 此 常 量 存 储 器 的 读 取 仅 需 在 缓 存 丢 失 时 读 取 一 次 设 备 存 储 器 , 否 则 只 需 读 取 常 量 缓 存 即 可 。<br />
warp<br />
warp<br />
度 一 样 快 。 成 本 随 着 所 有 线 程 读 取 的 不 同 地 址 的 数 量 增 加 而 线 性 增 加 。 我 们 建 议 , 使 整 个 的 所 有 线 程 都 读 取 相 同 的 地 址 , 而 不 仅 仅 是 保 证 各 半 中 的 所 有 线 程 都 读 取 相 同 的 地 址 , 因 为 未 来 速 的 器<br />
5.1.2.4 纹 理 存 储 器<br />
设 备 可 能 要 求 全 速 读 取 。 的<br />
warp 半 于 对<br />
的 所 有 线 程 来 说 , 只 要 所 有 线 程 都 读 取 同 一 个 地 址 , 从 常 量 缓 存 读 取 的 速 度 就 与 读 取 寄 存<br />
宽 要 求 , 但 不 涉 及 拾 取 延 迟 。 带<br />
(streaming 也 fetch),<br />
5.1.2.5 共 享 存 储 器<br />
理 存 储 器 空 间 会 被 缓 , 因 此 纹 理 拾 取 仅 需 在 缓 存 丢 失 时 读 取 一 次 设 备 存 储 器 , 否 则 只 需 读 取 纹 理 缓 存 纹<br />
从 全 局 存 储 器 或 常 量 存 储 器 读 取 设 备 存 储 器 的 方 法 相 比 , 通 过 纹 理 拾 取 读 取 设 备 存 储 器 可 能 是 一 种 更 有 与<br />
warp 。 纹 理 缓 存 已 为 二 维 空 间 位 置 而 优 化 , 因 此 读 取 相 邻 纹 理 地 址 的 同 一 个 可 即<br />
的 线 程 将 实 现 最 高 性<br />
于 共 享 存 储 位 于 芯 片 上 , 因 而 共 享 存 储 器 空 间 比 本 地 和 全 局 存 储 器 空 间 的 速 度 都 要 快 得 多 。 实 际 上 , 对 中 的 所 有 线 程 来 说 , 只 要 线 程 间 不 存 在 存 储 体 冲 突 问 共 享 存 储 器 的 速 度 就 与 访 问 寄 存 器 一 样 快 , 下 面 将 详 细 介 绍 相 关 内 容 。 由<br />
于 warp<br />
能 。 此 外 , 它 设 计 用 于 以 固 定 的 延 迟 执 行 流 式 拾 取<br />
DRAM 说 , 一 次 缓 存 命 中 将 减 少 是 就<br />
44 <strong>CUDA</strong><br />
但 若 一 个 储 器 请 求 的 两 个 地 址 落 入 同 一 个 存 储 体 内 , 就 会 出 现 存 储 体 冲 突 , 访 问 必 须 串 行 化 。 硬 件 会 在 必 要 时 将 存 在 存 储 体 冲 突 的 存 储 器 请 求 分 割 为 多 个 不 冲 突 的 请 求 , 此 时 有 效 带 宽 将 降 低 为 原 带 宽 除 以 分 离<br />
编<br />
5.4 的 替 代 方 法 , 详 见 第 势 优<br />
。<br />
实 现 , 得 到 更 高 效 的 带 宽 , 可 达 到 单 独 一 个 模 块 的 带 宽 的 n<br />
。<br />
这<br />
2.0 南 , 版 本 指 程<br />
为 了 获 得 较 高 的 存 储 器 带 宽 , 共 享 存 储 器 被 划 分 为 多 个 大 小 相 等 的 存 储 器 模 块 , 称 为 存 储 体<br />
n 储 体 可 同 时 访 问 。 因 此 , 对 落 入 存 些<br />
n 存 储 体 的 同 不<br />
地 址 的 任 何 存 储 器 读 取 或 写 入 请 求 都 可 同 时<br />
n 存 储 器 请 求 的 数 量 。 如 果 分 离 后 的 存 储 器 请 求 数 量 为 n, 就 可 以 说 初 始 存 储 器 请 求 导 致 了 的 后
块<br />
和<br />
展<br />
个 的 位<br />
,warp<br />
块 块 块<br />
位<br />
位<br />
是<br />
展<br />
块<br />
等<br />
时<br />
节<br />
是<br />
(stride)<br />
位<br />
块<br />
和<br />
是 时<br />
__shared__ float shared[32];<br />
float data = shared[BaseIndex + s * tid];<br />
存<br />
的 和 访 的 是<br />
位<br />
tid 进<br />
的<br />
块<br />
的<br />
突 。<br />
存 储 体 冲 突 。 为 了 获 得 最 大 化 的 性 能 , 有 必 要 理 解 存 储 器 地 址 如 何 映 射 到 存 储 体 以 调 度 存 储 器 请 求 , 以 最 小 化 存 储 体 冲<br />
(n-way)<br />
32 共 享 存 储 器 空 间 , 存 储 体 采 用 了 这 样 一 种 组 织 方 式 : 为 连 续 的 存 储 体 分 配 连 续 的 于 对<br />
字 , 每 个 存 储<br />
32 带 宽 都 是 的 体<br />
/2<br />
钟 周 期 。 时<br />
1.x 计 算 能 力 为 于 对<br />
设 备<br />
大 小 是 32, 的<br />
体 的 数 量 为 16( 储<br />
5.1 第 见<br />
);warp<br />
的 共<br />
参<br />
为<br />
warp 储 器 请 求 将 分 割 为 一 个 针 对 存 享<br />
warp 部 分 的 请 求 和 一 个 针 对 半 上<br />
下 半 部 分 的 请 求 。 因 而 , 属<br />
于 warp<br />
warp 部 分 的 线 程 和 属 于 一 第<br />
二 部 分 的 线 程 之 间 不 可 能 出 现 存 储 体 冲 突 。 第<br />
32 常 见 的 情 况 就 是 各 线 程 访 问 数 组 中 的 种 一<br />
ID 使 用 线 程 , 字<br />
行 索 引 , 步 幅<br />
s:<br />
是<br />
的<br />
s*n 例 中 , 只 要 本 在<br />
m 体 储 存<br />
n , 或 者 说 只 要 数 倍<br />
m/d<br />
d ( 其 中 数 倍<br />
m<br />
s<br />
最 大 公<br />
char 数<br />
__shared__ char shared[32];<br />
char data = shared[BaseIndex + tid];<br />
, 则 将 出 现 存 储 体 冲 突 : 组<br />
和<br />
位<br />
属<br />
tid ), 线 程 数 约<br />
tid+n<br />
warp 就 是 同 一 个 存 储 体 。 因 而 , 只 有 在 的 问<br />
m/d 半 大 小 小 于 等 于 一 的<br />
,<br />
1.x 会 存 在 存 储 体 冲 突 。 对 于 计 算 能 力 是 不 才<br />
d , 可 以 说 只 有 在 备 设<br />
于 1<br />
s 者 说 只 有 在 或 ,<br />
图 5-5<br />
图 5-6<br />
5-7 无 冲 突 存 储 器 访 问 的 示 例 , 图 了 示<br />
了 导 致 存 储 体 冲 突 的 存 储 器 访 问 示 例 。 示<br />
char data = shared[BaseIndex + 4 * tid];<br />
double<br />
__shared__ double shared[32];<br />
double data = shared[BaseIndex + tid];<br />
位 数<br />
突 , 但 若 通 过 以 下 方 式 访 问 同 一 个 数 组 : 路 冲<br />
操<br />
m 时 , 才 不 会 存 在 存 储 体 冲 突 , 因 为 数 奇<br />
2<br />
。 幂<br />
shared[0]、shared[1]、shared[2] 来 说 , 由 于 例 举<br />
shared[3]<br />
于 同 一 个 存 储 体 。 因 此 不 存 在 存 储 体<br />
32 值 得 注 意 的 情 况 还 包 括 在 各 线 程 访 问 小 于 或 大 于 他 其<br />
元 素 时 。 举 例 来 说 , 如 果 通 过 以 下 方 式 访 问 的<br />
__shared__ int shared_lo[32];<br />
__shared__ int shared_hi[32];<br />
double dataIn;<br />
shared_lo[BaseIndex + tid] = __double2loint(dataIn);<br />
shared_hi[BaseIndex + tid] = __double2hiint(dataIn);<br />
double dataOut =<br />
__hiloint2double(shared_hi[BaseIndex + tid],<br />
shared_lo[BaseIndex + tid]);<br />
数 分 割 为 两 部 分 , 如 以 下 示 例 代 码 所 示 : 作<br />
2 存 在 将 组<br />
储 体 冲 突 : 存<br />
__shared__ struct type shared[32];<br />
struct type data = shared[BaseIndex + tid];<br />
这 种 做 法 并 非 总 是 能 够 提 高 性 能 , 在 未 来 的 架 构 中 可 能 表 现 更 差 。 结 构 体 赋 值 将 在 必 要 时 编 译 为 针 对 结 构 体 中 各 成 员 的 多 个 存 储 器 请 求 , 因 此 , 以 下 代 码 : 但<br />
32 存 储 器 请 求 将 编 译 为 两 个 独 立 的 于 由<br />
double 。 在 本 例 中 避 免 存 储 体 冲 突 的 方 法 之 一 就 是 将 求 请<br />
如<br />
定<br />
struct type {<br />
:<br />
};<br />
float x, y, z;<br />
如<br />
得 到 以 下 结 果 将<br />
定<br />
struct type {<br />
float x, y;<br />
};<br />
如<br />
定<br />
struct type {<br />
<strong>CUDA</strong> 编<br />
45<br />
果 type<br />
如 下 , 则 进 行 两 次 有 存 储 体 冲 突 的 存 储 器 读 取 : 义<br />
果 type<br />
如 下 , 则 进 行 三 次 无 存 储 体 冲 突 的 存 储 器 读 取 : 义<br />
32 因 为 每 个 成 员 都 是 使 用 三 个 是 这<br />
作 为 步 幅 访 问 的 。 字<br />
32 因 为 每 个 成 员 都 是 使 用 两 个 是 这<br />
作 为 步 幅 访 问 的 。 字<br />
2.0 南 , 版 本 指 程<br />
果 type<br />
如 下 , 则 进 行 两 次 有 存 储 体 冲 突 的 存 储 器 读 取 : 义
展<br />
位<br />
(step),<br />
个<br />
块<br />
(random<br />
无<br />
permutation)。<br />
块<br />
(subset)<br />
位<br />
位<br />
位<br />
字 内 的 地 址 时 , 这 会<br />
};<br />
float f;<br />
char c;<br />
字 的 存 储 器 读 取 请 求 提 供<br />
5 因 为 每 个 成 员 都 是 使 用 是 这<br />
选<br />
终 , 共 享 存 储 器 也 会 运 用 一 种 广 播 服 务 时 同 步 将 其 读 取 并 广 播 给 多 个 线 程 。 在 最<br />
半 warp<br />
32 从 而 能 够 在 对 一 个 , 制<br />
子<br />
节 作 为 步 幅 访 问 的 。 机 减 少 存 储 体 冲 突 的 数 量 。 更 精 确 地 来 说 , 包 含 多 个 地 址 的 存 储 器 读 取 请 求 是 通 过 几 个 步 骤 逐 渐 完 成 的 —— 字<br />
提<br />
(broadcas)<br />
广<br />
每<br />
32 个 线 程 读 取 同 一 个 多 的<br />
剩<br />
两 个 时 钟 周 期 一 步 为 一 个 无 存 储 体 冲 突 子 集 提 供 服 务 ; 在 每 个 步 骤 中 都 通 过 以 下 步 骤 在 尚 未 被 服 务 的 地 址 中 建 立 子 集 : 每<br />
供 服 务 , 直 至 为 所 有 地 址<br />
剩 一 个 字 作 为 广 播 字 ; 集 中 包 括 : 播 字 内 的 所 有 地 址 ; 择<br />
地 址 指 向 的 各 存 储 体 的 地 址 。 不 指 定 在 每 个 周 期 选 择 哪 个 字 作 为 广 播 字 以 及 为 各 存 储 体 选 择 哪 个 地 址 。 余<br />
图 5-8<br />
了 包 括 广 播 机 制 在 内 的 存 储 器 读 取 访 问 的 示 例 。 示<br />
warp 常 见 的 无 冲 突 情 况 就 是 半 种 一<br />
32 所 有 线 程 都 读 取 同 一 个 的 中<br />
内 的 地 址 。 字<br />
右 侧 : 随 机 排 列<br />
无 存 储 体 冲 突 的 共 享 存 储 器 访 问 模 式 示 例<br />
的 线 性 寻 址 。 字<br />
46 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程<br />
32 : 步 幅 为 一 个 侧 左<br />
图 5-5.
位<br />
的 线 性 寻 址 。 字<br />
程 指 南 , 版<br />
无 存 储 体 冲 突 的 共 享 存 储 器 访 问 模 式 示 例<br />
<strong>CUDA</strong> 编<br />
47<br />
32 为 三 个 幅 步<br />
图 5-6.<br />
本 2.0
个 位<br />
位<br />
有<br />
例<br />
二 字 的 线 性 寻 址 将 导 致 八 路 存 储 体 冲 突 。<br />
例 有 存 储 体 冲 突 的 共 享 存 储 器 访 问 模 式 示 2 : 步 幅 为 侧 左<br />
图 5-7.<br />
32<br />
48 <strong>CUDA</strong> 编<br />
8 : 步 幅 为 侧 右<br />
32<br />
2.0 南 , 版 本 指 程
的<br />
。<br />
个<br />
使 用 广 播 机 制 的 共 享 存 储 器 读 取 访 问 模 式 示 例<br />
或<br />
类<br />
内<br />
内 的 地 址 。 的 字 在 第 一 个 步 中 被 选 作 广 播 字 ), 要 么 位<br />
5.1.2.6 寄 存 器<br />
存 储 体 冲 突 路 二 致 导 会<br />
寄 存 器<br />
<strong>CUDA</strong> 编<br />
49<br />
32 : 这 种 访 问 模 式 不 存 在 冲 突 , 因 为 所 有 线 程 都 读 取 同 一 个 侧 左<br />
5 : 这 种 访 问 模 式 要 么 不 会 导 致 存 储 体 冲 突 ( 如 果 存 储 体 侧 右<br />
图 5-8.<br />
般 而 言 , 访 问 寄 存 器 不 会 给 每 条 指 令 带 来 额 外 的 时 钟 周 期 , 但 写 入 后 读 取 依 赖 关 系 和 寄 存 器 的 存 储 体 冲 突 可 能 会 导 致 延 迟 。 一<br />
译 器 和 线 程 调 度 程 序 将 尽 可 能 以 最 优 方 式 调 度 指 令 , 避 免 出 现 寄 存 器 的 存 储 体 冲 突 。 当 每 个 块 的 线 程 数 编<br />
float4 来 说 , 无 需 将 数 据 转 换 成 体 具<br />
int4<br />
。 型<br />
2.0 南 , 版 本 指 程<br />
192 每 个 多 处 理 器 至 少 有 果 如<br />
动 线 程 , 写 入 后 读 取 依 赖 关 系 带 来 的 延 迟 可 忽 略 不 计 。 活<br />
64 是 量<br />
倍 数 时 , 这 种 方 法 的 效 果 最 优 。 除 了 遵 从 此 规 则 之 外 , 应 用 程 序 无 法 直 接 控 制 这 些 存 储 体 冲 突 。
,ceil(T,<br />
节<br />
的<br />
个<br />
的<br />
选<br />
块<br />
或<br />
块<br />
块<br />
或<br />
,B<br />
或<br />
所<br />
个<br />
节<br />
块<br />
或<br />
。<strong>CUDA</strong><br />
,T<br />
或<br />
个<br />
5.2 每 个 块 的 线 程 数 量<br />
定 每 个 网 格 的 线 程 总 数 、 每 线 程 总 数 ( 网 格 包 含 的 块 数 ), 应 选 择 最 大 化 可 用 计 算 资 源 的 利 用 率 。 这 意 味 着 块 的 数 量 至 少 应 与 设 备 中 的 多 处 理 器 数 量 相 同 。 此 外 , 每 个 多 处 理 器 仅 运 行 一 个 块 将 使 多 处 理 器 在 线 程 同 步 过 程 中 出 现 空 闲 , 如 果 每 个 块 中 没 有 足 够 的 线 给<br />
程 可 容 纳 负 载 延 迟 , 则 在 设 备 存 储 器 读 取 过 程 中 也 会 出 现 空 闲 。 因 而 , 最 好 允 许 在 每 个 多 处 理 器 上 存 在 两<br />
或 多 个 活 动 块 , 从 而 允 许 等 待 块 与 运 行 的 块 间 存 在 重 叠 。 为 此 , 块 的 数 量 至 少 应 为 设 备 中 多 处 理 器 数 量 的 二 倍 , 而 且 为 每 个 块 所 分 配 的 共 享 存 储 器 也 至 少 应 为 每 个 多 处 理 器 可 用 的 共 享 存 储 器 总 量 的 一 半 ( 请 参 见 )。 如 果 有 更 多 的 线 程 块 以 流 水 线 的 形 式 通 过 设 备 , 则 开 销 将 进 一 步 降 低 。 个<br />
代 的 设 备 上 。 的 节 数<br />
每 个 块 分 配 更 多 线 程 可 实 现 有 效 的 时 间 分 割 , 但 每 个 块 的 线 程 越 多 , 每 个 线 程 可 用 的 寄 存 器 就 越 少 。 如 为<br />
第 3.1<br />
线 程 数<br />
附<br />
出 的 各 多 处 理 器 的 寄 存 器 总 数 每 个 多 处 理 器 的 活 动 块 数 量 倍 数 。 给<br />
每 个 块 的<br />
32) 是 中 是<br />
四<br />
的<br />
是<br />
是<br />
100;1000 希 望 网 格 有 能 力 扩 展 到 未 来 的 设 备 , 每 个 网 格 的 块 数 量 至 少 应 为 果 如<br />
块 将 能 够 扩 展 到 此 后<br />
内 核 编 译 时 使 用 了 超 过 执 行 配 置 允 许 数 量 的 寄 存 器 , 这 可 能 会 妨 碍 内 核 调 用 。 果<br />
warp 的 数 量 足 够 多 后 , 每 个 块 的 线 程 数 量 应 为 块 在<br />
warp 的 倍 数 , 避 免 因 小 大<br />
填 充 不 足 而 造 成 的 计<br />
64 源 浪 费 , 最 好 使 线 程 数 量 是 资 算<br />
5.1.2.6 , 详 见 第 数 倍<br />
述 。 所<br />
1.x 计 算 能 力 为 于 对<br />
备 来 说 , 每 个 线 程 可 用 的 寄 存 器 数 量 等 于 : 设<br />
long<br />
long, 计 变<br />
R 中 其<br />
录 A<br />
将 T<br />
32 入 为 最 接 近 的 五 舍<br />
–ptxas-options=-v 在 编 译 时 使 用 果 如<br />
, 编 译 器 将 报 告 内 核 编 译 所 使 用 的 寄 存 器 数 量 ( 以 及 本 地 、 共 享 更 高 的 设 备 的 每 个 多 处 理 器 的 寄 存 器 数 量 都 是 项<br />
double 量 存 储 器 使 用 情 况 )。 请 注 意 , 每 个 常 和<br />
long<br />
量 都 为 本 地 支 持 这 些 类 型 的 设 备 使 用 两 个<br />
最 大 化 占 用 率 , 编 译 器 会 尝 试 最 小 化 寄 存 器 的 使 用 , 程 序 员 需 要 谨 慎 选 择 执 行 配 置 供 了 一 份 电 子 表 格 , 可 帮 助 程 序 员 根 据 共 享 存 储 器 和 寄 存 器 要 求 选 择 线 程 块 的 大 小 。 为<br />
1.2 器 , 也 就 是 计 算 能 力 为 存 寄<br />
更 高 的 设 备 对 应<br />
高 的 设 备 对 应 于 更<br />
Development Kit 提<br />
Software<br />
线<br />
于 long<br />
1.3 力 为 能 算<br />
但 计 算 能 力 低<br />
double。<br />
1.2 算 能 力 较 低 的 设 备 相 比 , 计 算 能 力 为 计 与<br />
于 1.2<br />
5.3 宿 主 和 设 备 间 的 数 据 传 输<br />
备 的 二 倍 。 程 是 更 理 想 的 情 况 , 允 许 使 用 足 够 的 寄 存 器 进 行 编 译 。 设<br />
64 块 最 少 有 个 每<br />
192 , 这 仅 在 每 个 多 处 理 器 有 多 个 活 动 块 时 才 是 有 意 义 的 。 每 个 块 程 线<br />
256<br />
warp 多 处 理 器 活 动 个 每<br />
warp 与 活 动 量 数<br />
A 数 量 ( 如 附 录 大 最<br />
示 ) 的 比 率 称 为 多 处 理 器 占 用 率 。<br />
和 设 备 存 储 器 之 间 的 带 宽 比 设 备 存 储 器 和 宿 主 存 储 器 之 间 的 带 宽 高 得 多 。 因 而 , 应 尽 力 最 小 化 宿 主 和 设 备 之 间 的 数 据 传 输 , 例 如 , 将 更 多 代 码 从 宿 主 迁 移 到 设 备 —— 即 便 这 意 味 着 以 并 行 性 更 低 的 计 算 方 式 运 行 内 核 。 设 备 存 储 器 中 可 能 会 创 建 中 间 数 据 结 构 , 由 设 备 , 而 且 在 销 毁 时 不 会 被 宿 主 映 射 , 也 不 会 复 制 到 宿 主 存 储 器 。<br />
外 , 考 虑 到 与 每 相 关 的 开 销 , 将 多 个 较 小 的 传 输 操 作 整 合 为 一 次 较 大 的 成 批 传 输 操 作 的 性 能 总 是 优 于 分 别 进 行 每 一 次 传 输 。 此<br />
50 <strong>CUDA</strong> 编<br />
4.5.1.2 , 在 使 用 分 页 锁 定 存 储 器 时 , 宿 主 和 设 备 间 的 带 宽 更 高 , 如 第 后 最<br />
述 。 所<br />
2.0 南 , 版 本 指 程
节<br />
位<br />
数<br />
之<br />
节<br />
节<br />
或<br />
(locality),<br />
数<br />
位<br />
节<br />
节<br />
5.4 纹 理 拾 取 与 全 局 或 常 量 存 储 器 读 取 的 对 比<br />
<br />
<br />
它<br />
节<br />
节<br />
寻<br />
打<br />
<br />
8<br />
4.3.4.1 节 位<br />
1.0]<br />
;<br />
1.0] 区<br />
是 缓 存 的 , 因 而 假 如 纹 理 拾 取 中 存 在 数 据 局 部 性 理 拾 取 将 表 现 出 更 高 的 带 宽 ; 它 们 不 受 制 于 存 储 器 访 问 模 式 的 限 制 , 而 全 局 或 常 量 存 储 器 读 取 必 须 遵 从 此 类 限 制 以 获 得 较 好 的 性 能<br />
读 取 全 局 或 常 量 存 储 器 相 比 , 通 过 纹 理 拾 取 实 现 设 备 存 储 器 读 取 有 着 一 些 优 势 : 纹 与<br />
计 算 的 延 迟 得 到 了 更 好 的 隐 藏 , 可 能 改 进 执 行 随 机 数 据 访 问 的 应 用 程 序 的 性 能 ; 址<br />
包 的 数 据 可 通 过 一 次 操 作 广 播 给 不 同 的 变 量<br />
5.1.2.1 参 见 第 请 (<br />
和 5.1.2.3<br />
);<br />
)。<br />
和 16<br />
[0.0, 输 入 数 据 可 转 换 为 型 整<br />
[-1.0,<br />
32 的 内 间<br />
点 值 ( 请 参 见 第 浮<br />
, 特 别 是 图 像 处 理 :<br />
特 性<br />
适 用 场 景 用<br />
提 示<br />
5.5 整 体 性 能 优 化 策 略<br />
一 的 纹 理 坐 标 独 立 于 分 辨 率 的 编 码 寻 址 模 式 自 动 处 边 界 情 况 仅 适 用 于 归 一 化 坐 标 但 在 个 内 核 调 用 中 , 纹 理 缓 存 不 会 在 全 局 存 储 器 写 入 方 面 保 持 连 贯 性 , 因 此 如 果 纹 理 拾 取 针 对 的 是 通 归<br />
<strong>CUDA</strong><br />
化<br />
一 内 核 调 用 的 全 局 写 入 操 作 写 入 的 地 址 , 则 将 返 回 不 确 定 的 数 据 。 换 句 话 说 仅 在 存 储 器 位 置 已 由 之 前 内 核 调 用 存 储 器 复 制 更 新 时 , 线 程 才 能 通 过 纹 理 安 全 读 取 某 些 存 储 器 位 置 , 但 如 果 已 由 同 一 内 核 调 用 的 同 一 线 程 或 其 他 线 程 更 新 , 则 并 非 如 此 。 二 者 仅 在 使 用 无 法 写 入 组 的 内 核 从 线 性 存 储 器 拾 取 时 才 有 所 相 关 。 同 过<br />
<strong>CUDA</strong> 纹 理 是 一 个 果 如<br />
4.3.4.2 请 参 见 第 ( 组<br />
), 硬 件 提 供 的 其 他 功 能 可 能 对 不 同 的 应 用 程 序 非 常 有<br />
Texel 滤 过<br />
的 快 速 、 低 精 度 的 插 值 仅 在 纹 理 参 考 返 回 浮 点 数 据 时 有 效 间<br />
最<br />
能 优 化 是 以 三 项 基 本 策 略 为 基 础 演 化 出 来 的 : 大 化 并 行 执 行 ; 性<br />
优<br />
优<br />
__syncthreads(), 在<br />
需 要 同 步 以 彼 此 共 享 数 据 而 被 打 破 时 可 能 出 现 两 种 情 况 : 这 些 线 程 可 能 属 于 同 一 个 块 , 此 时 应 使 用 同 一 个 内 核 调 用 中 同 步 共 享 存 储 器 共 享 数 据 ; 如 果 属 于 不 同 的 块 , 此 时 必 须 使 用 两 个 独 立 的 内 核 调 用 通 过 全 局 存 储 器 共 享 数 据 , 一 个 用 于 写 入 全 局 存 储 器 , 一 个 用 于 读 取 全 局 存 储 器 。 程<br />
存 储 器 利 用 率 , 实 现 最 大 的 存 储 器 带 宽 ; 化 指 令 利 用 率 , 实 现 最 大 化 的 指 令 吞 吐 量 。 最 大 化 并 行 执 行 的 第 一 步 就 是 结 构 化 算 法 , 尽 可 能 地 寻 找 到 更 多 的 数 据 并 行 性 。 当 算 法 的 并 行 性 因 某 些 线<br />
一 旦 算 法 的 并 行 性 被 找 到 , 就 需 要 尽 可 能 有 效 地 在 硬 件 实 现 。 这 是 通 过 谨 慎 选 择 各 内 核 调 用 的 执 行 配 置 完<br />
节 现 数 量 级 的 变 化 。 优 化 存 储 器 利 用 率 的 下 一 步 骤 是 根 据 最 优 的 存 储 器 访 问 模 式 , 尽 可 能 以 最 优 方 式 组 织 存 和<br />
用 程 序 还 应 最 大 化 宿 主 和 设 备 间 的 并 发 执 行 。 优 化 存 储 器 利 用 率 的 第 一 步 是 最 小 化 低 带 宽 的 数 据 传 输 。 这 也 就 意 味 着 最 小 化 宿 主 和 设 备 之 间 的 数 据 传 应<br />
<strong>CUDA</strong> 编<br />
51<br />
4.5.1.5 程 序 还 应 在 较 高 的 层 面 最 大 化 并 行 执 行 , 通 过 流 在 设 备 上 显 式 寻 找 并 发 执 行 , 如 第 用 应<br />
所 述 ,<br />
5.2 , 详 细 内 容 请 参 见 第 的 成<br />
。<br />
佳 优 化 方 法 可 能 是 首 先 避 免 进 行 任 何 数 据 传 输 , 直 接 在 需 要 的 位 置 重 新 计 算 数 据 。 最<br />
5.1.2.1、5.1.2.3、5.1.2.4 第 如<br />
5.1.2.5<br />
所 述 , 根 据 各 类 存 储 器 的 访 问 模 式 的 不 同 , 有 效 带 宽 可 能 会 出<br />
2.0 南 , 版 本 指 程<br />
5.3 如 第 , 输<br />
所 述 , 因 为 此 类 传 输 比 设 备 和 全 局 存 储 器 之 间 的 数 据 传 输 带 宽 低 得 多 。 这 也 意 味 着 通 过 最<br />
5.1.2 设 备 共 享 存 储 器 的 使 用 来 尽 可 能 地 减 少 设 备 和 全 局 存 储 器 之 间 的 数 据 传 输 , 如 第 化 大<br />
所 述 。 有 时 ,
节<br />
特<br />
(B.2 节 节 器 访 问 。 这 种 优 化 对 于 全 局 存 储 器 访 问 尤 为 重 要 , 因 为 全 局 存 储 器 的 带 宽 较 低 , 其 延 迟 可 能 达 到 百 个 进 行 共 享 存 储 器 访 问 优 化 。 储<br />
, 在 不 影 响 最 终 结 果 的 前 提 下 提 高 速 度 , 例 如 使 用 内 建 函 数 而 非 一 般 函 数 列 举 了 内 建 函 数 )、 度<br />
5.1.1.3 周 期 ( 请 参 见 第 钟 时<br />
)。 另 一 方 面 , 通 常 只 有 在 共 享 存 储 器 访 问 中 存 在 严 重 的 存 储 体 冲 突 时 才<br />
5.1.1.1 指 令 利 用 率 的 优 化 , 应 最 小 化 低 吞 吐 量 的 数 学 指 令 的 使 用 ( 请 参 见 第 于 对<br />
)。 这 包 括 权 衡 计 算 精<br />
SIMT 单 精 度 而 非 双 精 度 。 由 于 设 备 的 用 使<br />
5.1.1.2 应 特 别 注 意 控 制 流 指 令 , 如 第 , 性<br />
述 。 所<br />
52 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
相<br />
所<br />
选<br />
,Csub 等<br />
更 高 的 通 用 矩 阵 乘 法 实 现 。 能<br />
的<br />
和<br />
的<br />
的<br />
程 指 南 , 版<br />
和<br />
的 的 的<br />
编<br />
矩<br />
的<br />
块<br />
的<br />
的<br />
节<br />
同 时 保 的 子 阵 , 它 的 行 索 引 ),<br />
第 6 章 矩 阵 乘 法 示 例<br />
6.1 概 述<br />
hA)<br />
wA) 的<br />
<br />
块<br />
程<br />
Csub<br />
线<br />
的<br />
为 (wA,<br />
(wB,<br />
wA)<br />
一 个 子 方 矩<br />
录 A)。 使<br />
block_size)<br />
积 C, 此 任 务 将 以 如 下 方 法 划 分 为 几 个 乘<br />
小 的 倍 数 ( 请 参 见 具 大<br />
阵 A<br />
B 阵 矩<br />
C 线 程 块 均 负 责 计 算 个 每<br />
计 算 维 度 分 别<br />
阵 Csub;<br />
:<br />
证 不 超 过 每 个 块 的 最 大 线 程 数 ( 附 示 维<br />
Csub 每 个 线 程 负 责 计 算 的 内<br />
一 个 元 素<br />
度 block_size<br />
。<br />
为 16,<br />
warp 块 的 线 程 数 是 个 每<br />
第 5.2<br />
如<br />
和<br />
的<br />
/ block_size)。<br />
为 block_size<br />
图 6-1<br />
通 过 这 种 方 法 安 排 计 算 , 我 们 就 利 用 了 速 度 较 快 的 共 享 存 储 器 , 节 省 了 大 量 全 局 存 储 器 带 宽 , 这 是 因 为 从<br />
(wA, 下 两 个 长 方 矩 阵 的 乘 积 : 维 度 为 以 于<br />
A<br />
方 阵 , 通 过 计 算 这 些 方 阵 的 乘 积 和 来 计<br />
源 , 这 两 个 长 方 矩 阵 被 分 割 为 多 维 度 每 个 乘 积 首 先 都 从 全 局 存 储 器 将 两 个 对 应 的 方 阵 载 入 共 享 存 储 器 , 使 用 一 个 线 程 载 入 各 矩 阵 的 一 个 元 素 , 然 后 由 各 线 程 来 计 算 乘 积 的 一 个 元 素 。 各 线 程 将 所 有 这 些 乘 积 的 结 果 汇 总 到 一 个 寄 存 器 中 , 完 成 后 , 将 结 果 写 入 全 局 存 储 器 。 资<br />
算 Csub。<br />
与 Csub<br />
(block_size, 维 度 为 ; 同<br />
B<br />
Csub , 它 与 阵 子<br />
有 相 同 的 列 索 引 。 为 了 适 应 设 备 的<br />
A 存 储 器 中 读 取 局 全<br />
B<br />
(wA 仅 为 数 次<br />
<strong>CUDA</strong> 编 写 本 示 例 时 , 我 们 仅 以 展 示 各 种 在 而<br />
程 原 则 为 目 标 , 所 以 在 实 际 应 用 中 , 请 探 索 比 本 示 例 性<br />
每 个 线 程 块 计<br />
一 个 子 矩<br />
内 的 每 个 线 程 计<br />
个 元 素 。 一<br />
<strong>CUDA</strong> 编<br />
53<br />
矩 阵 乘 法 块<br />
本 2.0<br />
算 C<br />
阵 Csub。<br />
算 Csub<br />
图 6-1.
6.2 源 代 码 清 单<br />
// Thread block size<br />
#define BLOCK_SIZE 16<br />
// Forward declaration of the device multiplication function<br />
__global__ void Muld(float*, float*, int, int, float*);<br />
// Host multiplication function<br />
// Compute C = A * B<br />
// hA is the height of A<br />
// wA is the width of A<br />
// wB is the width of B<br />
void Mul(const float* A, const float* B, int hA, int wA, int wB,<br />
float* C)<br />
{<br />
int size;<br />
// Load A and B to the device<br />
float* Ad;<br />
size = hA * wA * sizeof(float);<br />
cudaMalloc((void**)&Ad, size);<br />
cudaMemcpy(Ad, A, size, cudaMemcpyHostToDevice);<br />
float* Bd;<br />
size = wA * wB * sizeof(float);<br />
cudaMalloc((void**)&Bd, size);<br />
cudaMemcpy(Bd, B, size, cudaMemcpyHostToDevice);<br />
// Allocate C on the device<br />
float* Cd;<br />
size = hA * wB * sizeof(float);<br />
cudaMalloc((void**)&Cd, size);<br />
// Compute the execution configuration assuming<br />
// the matrix dimensions are multiples of BLOCK_SIZE<br />
dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);<br />
dim3 dimGrid(wB / dimBlock.x, hA / dimBlock.y);<br />
// Launch the device computation<br />
Muld(Ad, Bd, wA, wB, Cd);<br />
// Read C from the device<br />
cudaMemcpy(C, Cd, size, cudaMemcpyDeviceToHost);<br />
// Free device memory<br />
cudaFree(Ad);<br />
cudaFree(Bd);<br />
cudaFree(Cd);<br />
}<br />
// Device multiplication function called by Mul()<br />
// Compute C = A * B<br />
// wA is the width of A<br />
// wB is the width of B<br />
__global__ void Muld(float* A, float* B, int wA, int wB, float* C)<br />
{<br />
// Block index<br />
int bx = blockIdx.x;<br />
int by = blockIdx.y;<br />
// Thread index<br />
int tx = threadIdx.x;<br />
int ty = threadIdx.y;<br />
// Index of the first sub-matrix of A processed by the block<br />
int aBegin = wA * BLOCK_SIZE * by;<br />
// Index of the last sub-matrix of A processed by the block<br />
int aEnd = aBegin + wA - 1;<br />
// Step size used to iterate through the sub-matrices of A<br />
int aStep = BLOCK_SIZE;<br />
// Index of the first sub-matrix of B processed by the block<br />
int bBegin = BLOCK_SIZE * bx;<br />
// Step size used to iterate through the sub-matrices of B<br />
int bStep = BLOCK_SIZE * wB;<br />
// The element of the block sub-matrix that is computed<br />
// by the thread<br />
float Csub = 0;<br />
// Loop over all the sub-matrices of A and B required to<br />
// compute the block sub-matrix<br />
54 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
,Muld() 将<br />
的<br />
将 相<br />
的<br />
程 指 南 , 版<br />
的<br />
和<br />
中<br />
分<br />
所<br />
(wrapper);<br />
C; ; ; 和<br />
。<br />
}<br />
for (int a = aBegin, b = bBegin;<br />
a
,Csub 计<br />
是<br />
和<br />
都<br />
的<br />
,Muld() 会<br />
节<br />
,ty<br />
节<br />
节<br />
。<br />
,tx 在<br />
至<br />
<br />
再 计<br />
Muld() 的<br />
b<br />
和<br />
这 里 也 不 存 在 任 何 存 储 体 冲 突 , 因 为 在 每 个<br />
中<br />
15 之<br />
实 际 上 , 假<br />
存 等<br />
。<br />
块 对 于 所 有 线 程 都 是 相 同 的 和 存 储 器 访 问 时 都 会 访 问 不 同 储 器 访 问 时 访 问 相 同 的 存 储 体 。 的<br />
为 a、<br />
两 个 子 阵 的 乘 积 , 并 将 其 与 上 一 次 循 环 获 得 的 乘 积 相 加 ; 次 进 行 同 步 , 以 确 保 两 个 子 阵 的 乘 积 运 算 已 完 成 , 之 后 才 开 始 下 一 次 循 环 处 理 所 有 子 阵 之 后 算 完 成 将 结 果 写 入 全 局 存 储 器 。 算<br />
述 , 此 时 将 能 够 确 保 全 局 存 储 器 合 并 , 因 倍 数 。 所<br />
5.1.2.1 目 的 是 为 了 最 大 化 存 储 器 性 能 , 请 参 见 第 写 编<br />
5.1.2.5 第 和<br />
设 wA<br />
wB<br />
16<br />
5.1.2.1 , 如 第 数 倍<br />
c<br />
是 BLOCK_SIZE(<br />
半 warp<br />
于 16)<br />
0<br />
As[ty][tx]、Bs[ty][tx] 因 此 每 个 线 程 在 进 行 , 间<br />
k<br />
As[ty][k] 储 体 , 而 在 进 行 存 的<br />
Bs[k][tx]<br />
56 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
的<br />
节<br />
节<br />
节<br />
附 录 A 技 术 规 范<br />
A.1 一 般 规 范<br />
GeForce GTX 280 30 1.3<br />
GeForce GTX 260 24 1.3<br />
GeForce 9800 GX2 2×16 1.1<br />
GeForce 9800 GTX 16 1.1<br />
GeForce 8800 Ultra, 8800 GTX 16 1.0<br />
GeForce 8800 GT 14 1.1<br />
GeForce 9600 GSO, 8800 GS, 8800M GTX 12 1.1<br />
GeForce 8800 GTS 12 1.0<br />
GeForce 9600 GT, 8800M GTS 8 1.1<br />
GeForce 9500 GT, 8600 GTS, 8600 GT,<br />
面 的 内 容 描 述 了 与 各 种 计 算 能 力 相 关 联 的 技 术 规 范 和 特 性 。 若 无 其 他 说 明 , 给 定 计 算 能 力 的 规 范 与 略 低 计 算 能 力 的 规 范 相 同 。 类 似 地 , 计 算 能 力 向 下 兼 容 。 下 多 处 理 器 数 量<br />
计 算 能 力<br />
4 1.1<br />
8700M GT, 8600M GT, 8600M GS<br />
GeForce 8500 GT, 8400 GS, 8400M GT,<br />
8400M GS<br />
2 1.1<br />
GeForce 8400M G 1 1.1<br />
Tesla S1070 4×30 1.3<br />
Tesla C1060 30 1.3<br />
Tesla S870 4×16 1.0<br />
1.0<br />
4×16 2×16<br />
Tesla D870<br />
Tesla C870 16 1.0<br />
Quadro Plex 1000 Model S4 1.0<br />
Quadro Plex 1000 Model IV<br />
Quadro FX 5600 1.0<br />
Quadro FX 3700 14 1.1<br />
Quadro FX 3600M 12 1.1<br />
Quadro FX 4600 12 1.0<br />
Quadro FX 1700, FX 570, NVS 320M, FX 1600M,<br />
FX 570M<br />
4 1.1<br />
Quadro FX 370, NVS 290, NVS 140M, NVS 135M,<br />
FX 360M<br />
2 1.1<br />
Quadro NVS 130M 1 1.1<br />
2.5 设 备 的 一 般 规 范 取 决 于 其 计 算 能 力 ( 请 参 见 第 算 计<br />
)。<br />
<strong>CUDA</strong> 列 出 了 所 有 支 持 表 下<br />
备 的 多 处 理 器 数 量 和 计 算 能 力 : 设<br />
1.0<br />
A.1.1<br />
计 算 能 力 1.0 的 规 范<br />
<strong>CUDA</strong><br />
每 个 块 的 最 大 线 程 数 编<br />
和 )。<br />
57<br />
第 4.5.3.2<br />
2.0 南 , 版 本 指 程<br />
4.5.2.2 用 运 行 时 查 询 时 钟 频 率 和 设 备 存 储 器 总 量 ( 请 参 见 第 使 可<br />
为 512;
和<br />
维<br />
遇<br />
位<br />
(rounding<br />
和<br />
在<br />
节<br />
方<br />
;<br />
节<br />
)。<br />
字 上 操 作 的 原 子 函 数 ( 请 参 见 位<br />
舍<br />
的<br />
NaN) 编 码 , 但 实 异<br />
;<br />
Warp<br />
<br />
<br />
<br />
<br />
<br />
常 量 存 储 器 的 总 量 块<br />
<br />
<br />
每 纹<br />
<br />
<br />
对 <br />
32 程 线 个 内<br />
个<br />
程 ;<br />
可 用 的 共 享 存 储 器 数 量 组 线<br />
量 是 每 个 多 处 理 理 存 储 器 的 缓 存 工 作 区 介 于 每 个 多 处 理 到 个 多 处 理 器 的 最 大 活 动 块 数 是 8; 块 常<br />
8192;<br />
16KB,<br />
64KB;<br />
器 8KB;<br />
6 8KB<br />
是<br />
器 是 是<br />
于 绑 定 到 线 性 存 储 器 的 纹 理 参 考 , 最 大 宽 度 数 个 万<br />
指<br />
; 令<br />
16<br />
之 为 织<br />
27;<br />
个<br />
13;<br />
间<br />
11, 最 16,<br />
存 储 体 ( 请 参 见<br />
个<br />
11, 最 15;<br />
第 5.1.2.5<br />
节<br />
);<br />
11;<br />
块<br />
x、y 线 程 块 的 个 一<br />
z<br />
512、512 大 规 格 分 别 为 最 的<br />
64;<br />
程 块 网 格 各 维 度 的 最 大 规 格 为 65535; 线<br />
32 小 是 大 的<br />
个 多 处 理 器 的 寄 存 器 数 量<br />
warp 处 理 器 的 最 大 活 动 多 个<br />
是 24; 数<br />
多 处 理 器 的 最 大 活 动 线 程 数 是 768; 个<br />
<strong>CUDA</strong> 定 到 一 维 绑 于<br />
2 纹 理 参 考 , 最 大 宽 度 为 的 组<br />
<strong>CUDA</strong> 定 到 二 维 绑 于<br />
2 纹 理 参 考 , 最 大 宽 度 为 的 组<br />
2 度 为 高 大<br />
A.1.2<br />
计 算 能 力 1.1 的 规 范<br />
<strong>CUDA</strong> 定 到 三 维 绑 于<br />
2 纹 理 参 考 , 最 大 宽 度 为 的 组<br />
2 度 为 高 大<br />
2 度 为 深 大<br />
支<br />
A.1.3<br />
计 算 能 力 1.2 的 规 范<br />
计 算 能 力<br />
。<br />
为 2<br />
200 小 限 制 为 大 核<br />
PTX<br />
8 多 处 理 器 都 由 个 每<br />
4 器 组 成 , 因 此 一 个 多 处 理 器 能 够 在 理 处<br />
warp 周 期 内 处 理 一 个 钟 时<br />
<br />
<br />
<br />
每 支<br />
vote 函<br />
在 全 局 存 储 器 持<br />
持 在 共 享 存 储 器 中 操 作 的 原 子 函 数 以 及 在 全 局 存 储 器 支<br />
块<br />
的 32<br />
4.4.4 操 作 的 原 子 函 数 ( 请 参 见 第 上 字<br />
);<br />
A.1.4<br />
节<br />
计 算 能 力 1.3 的 规 范<br />
是 1024。<br />
的 64<br />
第 4.4.4<br />
支<br />
A.2 浮 点 标 准<br />
多 处 理 器 的 最 大 活 动 线 程 数 个<br />
双 精 度 浮 点 数 。 持<br />
持 warp<br />
4.4.5 请 参 见 第 ( 数<br />
多 处 理 器 的 寄 存 器 数 量 是 16384; 个<br />
);<br />
warp 处 理 器 的 最 大 活 动 多 个<br />
量 是 32; 数<br />
<br />
标<br />
mode); 但<br />
存 在 动 态 可 配 置 的 舍 入 模 式 函 数 公 开 ; 不<br />
<br />
, 但 有 以 下 例 外 : 入 模 式 , 可 通 过 设 备 准<br />
常 被 掩 藏 一 样 , 并 且 这 种 隐 藏 的<br />
绝<br />
58 <strong>CUDA</strong> 编<br />
存 在 检 测 发 生 浮 点 异 常 的 机 制 , 所 有 操 作 的 行 为 就 到 异 常 事 件 时 一 样 ; 同 样 , 尽 管 支 不<br />
IEEE-754 计 算 设 备 都 符 合 针 对 二 进 制 浮 点 算 术 的 有 所<br />
IEEE-574 和 负 数 不 符 合 值 对<br />
2.0 南 , 版 本 指 程<br />
IEEE 数 操 作 都 支 持 多 大<br />
NaN<br />
面 的 规 定 , 它 们 将 按 原 样 传 递<br />
像 IEEE-754<br />
与 IEEE-754<br />
持 SNaN(Signaling<br />
持 Signaling;<br />
达 方 式 际 上 不 支 表
(round-towards-zero),<br />
:<br />
(denormalized<br />
参<br />
程 指 南 , 版<br />
的<br />
它 (FMAD),<br />
(round-to-nearest-even)<br />
请 NaN),<br />
的<br />
构 的 处 理 方 式 不 同 。 架<br />
对<br />
<br />
精 度 浮 点 数 加 单 于<br />
<br />
<br />
<br />
<br />
平 除<br />
加<br />
number); 浮<br />
<br />
<br />
下<br />
- 乘 法 往 往 结 合 为 一 条 乘 和 法<br />
令 法 是 通 过 倒 数 、 以 非 标 准 的 方 式 实 现 的 ; 指<br />
截 取 乘 法 的 中 间 结 果 ; 将<br />
根 是 以 非 标 准 的 方 式 通 过 倒 数 平 方 根 实 现 的 ; 不 方<br />
和<br />
的 结 果 将 被 刷 新 为 零 ; 涉 及 一 个 或 多 个 输 操 作 的 结 果 是 位 模 意 : 溢<br />
加 以 注<br />
于 加 法 和 乘 法 , 仅 支 持 通 过 静 态 舍 入 模 式 实 现 舍 入 到 最 近 的 偶 数 零 舍 入 支 持 向 正 负 无 穷 大 方 向 的 舍 入 ; 对<br />
向<br />
仅<br />
<br />
标<br />
舍<br />
模 式 是 舍 入 到 最 近 的 偶 数 或 的 入<br />
其 但<br />
不 支 持 反 向 规 格 化 数<br />
点 算 术 和 比 较 指 令 会 在 浮 点 操 作 之 前 将 操 作 数 反<br />
规 格 化 为 零 ; 向<br />
于 双 精 度 浮 点 数 : 对<br />
IEEE-754<br />
而 言 , 采 用 将 数 限 定 在 所 支 持 的 范 围 尾 端 的 方 法 。 这 并<br />
入 NaN<br />
式 0x7fffffff<br />
QNaN(Quiet<br />
未 定 义 在 浮 点 值 超 出 整 型 格 式 的 范 围 的 情 况 下 , 浮 点 值 到 整 型 值 的 转 换 方 式 。 对 于 计 算 设 备<br />
NaN 数 不 是 , 则 结 果 为 非 参 他<br />
。 数<br />
IEEE 、 除 法 和 平 方 根 运 算 中 惟 一 支 持 的 数 倒<br />
IEEE-754R 据 根<br />
fminf()、fmin()、fmaxf() 如 果 , 准<br />
fmax()<br />
与 x86<br />
是 的 输 入 参 数 之 一 是 NaN,<br />
<strong>CUDA</strong> 编<br />
59<br />
本 2.0
加<br />
运<br />
节<br />
的<br />
数<br />
库<br />
节<br />
(mathematical library) standard 函<br />
ulp。 但<br />
(full<br />
误<br />
计<br />
。truncf()、ceilf()<br />
而<br />
。<br />
附 录 B 标 准 数 学 函 数<br />
B.1 节<br />
B.1 通 用 运 行 时 组 件<br />
中 的 函 数 仅 能 在 设 备 函 数 中 使 用<br />
各 函 数 在 设 备 上 执 行 时 的 误 差 范 围 。 当 函 数 在 宿 主 上 执 行 , 而 宿 主 并 未 提 供 此 函 数 时 , 误 差 范 围 同 样 适 用 。<br />
B.2 举 的 函 数 可 由 宿 主 和 设 备 函 数 使 用 , 但 列 中<br />
B.1.1<br />
单 精 度 浮 点 函 数<br />
和<br />
函<br />
。<br />
绍 <strong>CUDA</strong><br />
这 里 列 举 的 误 差 范 围 经 过 了 广 泛 的 测 试 , 但 并 非 详 尽 无 遗 , 所 以 很 难 保 证 正 确 无 误<br />
这 一 节 介<br />
行 时 库 支 持 的 所 有 数 学 标 准 库<br />
数 。 此 外 还 指 定 了<br />
可 映 射 到 一 条 指 令 。 均<br />
floorf() 也<br />
会<br />
指<br />
只<br />
和<br />
截 (FMAD),<br />
IEEE 和 乘 法 是 符 合 法 加<br />
0.5 此 误 差 最 多 为 因 ,<br />
在 设 备 上 , 编 译 器 往 往 将 其 整 合 为 一 个 单 独 的<br />
- 指 令 乘<br />
_fadd_rn() 法 的 中 间 结 果 。 可 通 过 使 用 乘 取<br />
_fmul_rn()<br />
数 来 避 免 这 样 的 整 合<br />
非 roundf()。<br />
x+y 0(IEEE-754 舍 错<br />
rintf() 单 精 度 浮 点 操 作 数 舍 入 为 整 型 , 而 使 结 果 为 单 精 度 浮 点 数 , 推 荐 的 方 法 是 使 用 将 要<br />
B.2 参 见 第 请 (<br />
)。<br />
原 因 在 于 roundf()<br />
8 到 设 备 上 的 一 个 射 映<br />
rintf() 列 , 而 序 令<br />
映 射 到 一 条 指 令<br />
x*y 0(IEEE-754 舍 时<br />
入 到 最 近 的 偶 数 ) 时 2( range))<br />
范 围 全<br />
x/y<br />
1/x 1 ( )<br />
1/sqrtf(x)<br />
2 ( )<br />
rsqrtf(x)<br />
sqrtf(x) 3 ( )<br />
cbrtf(x) 1 ( )<br />
hypotf(x,y) 3 ( )<br />
expf(x) 2 ( )<br />
exp2f(x) 2 ( )<br />
exp10f(x) 2 (<br />
expm1f(x) 1 (<br />
logf(x) 1 (<br />
log2f(x) 3 (<br />
log10f(x) 3 (<br />
log1pf(x) 2 (<br />
sinf(x) 2 (<br />
cosf(x) 2 (<br />
tanf(x) 4 (<br />
表 B-1.<br />
大 数 学 标 准 库 函 数 及 其 最 大 ULP<br />
误 差<br />
<strong>CUDA</strong> 误 差 表 示 为 正 确 舍 入 的 单 精 度 结 果 和 大 最<br />
ulp 返 回 的 结 果 之 间 以 数 函<br />
的 差 的 绝 对 值 。 算<br />
函 数<br />
大 最 大 ulp<br />
错 误<br />
FMAD 合 并 入 在 (<br />
外 ) 除<br />
FMAD 合 并 入 在 (<br />
外 ) 除<br />
60 <strong>CUDA</strong> 编<br />
) 围 范<br />
) 围 范<br />
) 围 范<br />
) 围 范<br />
2.0 南 , 版 本 指 程<br />
) 围 范<br />
)<br />
范 围 围 )<br />
) 围 范<br />
) 围 范
程 指 南 , 版<br />
内 间 外 距 全 范 围 sincosf(x,sptr,cptr) 2 (<br />
asinf(x) 4 ( )<br />
acosf(x) 3 ( )<br />
atanf(x) 2 ( )<br />
atan2f(y,x) 3 ( )<br />
sinhf(x) 3 ( )<br />
coshf(x) 2 ( )<br />
tanhf(x) 2 ( )<br />
asinhf(x) 3 ( )<br />
acoshf(x) 4 ( )<br />
atanhf(x) 3 ( )<br />
powf(x,y) 7 ( )<br />
erff(x) 4 ( )<br />
erfcf(x) 8 ( )<br />
lgammaf(x) 6 ( (outside interval)-10.001 ... -2.264;<br />
tgammaf(x) 11 ( )<br />
fmaf(x,y,z) 0 ( )<br />
frexpf(x,exp) 0 ( )<br />
ldexpf(x,exp) 0 ( )<br />
scalbnf(x,n) 0 ( )<br />
scalblnf(x,l) 0 ( )<br />
logbf(x) 0 ( )<br />
ilogbf(x) 0 ( )<br />
fmodf(x,y) 0 ( )<br />
remainderf(x,y) 0 ( )<br />
remquof(x,y,iptr) 0 ( )<br />
modff(x,iptr) 0 ( )<br />
fdimf(x,y) 0 ( )<br />
truncf(x) 0 ( )<br />
roundf(x) 0 ( )<br />
rintf(x) 0 ( )<br />
nearbyintf(x) 0 ( )<br />
ceilf(x) 0 ( )<br />
floorf(x) 0 ( )<br />
lrintf(x) 0 ( )<br />
lroundf(x) 0 ( )<br />
llrintf(x) 0 ( )<br />
llroundf(x) 0 ( )<br />
signbit(x)<br />
N/A<br />
isinf(x)<br />
N/A<br />
isnan(x)<br />
N/A<br />
isfinite(x)<br />
N/A<br />
copysignf(x,y)<br />
N/A<br />
fminf(x,y)<br />
N/A<br />
fmaxf(x,y)<br />
N/A<br />
fabsf(x)<br />
N/A<br />
nanf(cptr)<br />
N/A<br />
nextafterf(x,y)<br />
N/A<br />
) 更 大 距 间<br />
) 围 范<br />
<strong>CUDA</strong> 编<br />
61<br />
本 2.0
或<br />
会<br />
类<br />
数<br />
指<br />
库<br />
仅<br />
错<br />
计<br />
。Trunc()、ceil() 和<br />
B.1.2<br />
双 精 度 浮 点 函 数<br />
floor() 均<br />
面 列 举 的 误 差 仅 适 用 于 为 具 有 本 地 双 精 度 支 持 的 设 备 编 译 的 情 况 。 在 为 无 此 类 支 持 的 设 备 编 译 时 ( 如 计 双 而 原 因 在 映 射 到 一 条 指 令 下<br />
是 round()。<br />
的 差 的 绝 对 值 。 算<br />
算 能 力 为 1.2<br />
更 低 的 设 备 ),double<br />
将 默 认 地 降 低 为 float, 型<br />
度 数 学 函 数 将 映 射 为 其 单 精 度 版 本 。 精<br />
将 双 精 度 浮 点 操 作 数 舍 入 为 整 型 , 而 使 结 果 为 双 精 度 浮 点 数 , 推 荐 的 方 法 是 使 用 rint(), 要<br />
不<br />
B-2.<br />
到 设 备 上 的 一 可 映 射 到 一 条 指 令 。 表 映 射 函 数<br />
序 列 , 错 误 令 错 误 入 到 最 近 的 偶 数 )<br />
最 的 数 入 近 到 舍 ) 偶 围 范<br />
更 间 入 内 到 舍 最 近 的 偶 数 ) 间 外 距<br />
全<br />
x+y 0 (IEEE-754<br />
x*y 0 (IEEE-754<br />
x/y 0 (IEEE-754<br />
1/x 0 (IEEE-754<br />
sqrt(x) 0 (IEEE-754<br />
rsqrt(x) 1 ( )<br />
cbrt(x) 1 ( )<br />
hypot(x,y) 2 ( )<br />
exp(x) 1 ( )<br />
exp2(x) 1 ( )<br />
exp10(x) 1 ( )<br />
expm1(x) 1 ( )<br />
log(x) 1 ( )<br />
log2(x) 1 ( )<br />
log10(x) 1 ( )<br />
log1px(x) 1 ( )<br />
sin(x) 2 ( )<br />
cos(x) 2 ( )<br />
tan(x) 3 ( )<br />
sincos(x,sptr,cptr) 2 ( )<br />
asin(x) 2 ( )<br />
acos(x) 2 ( )<br />
atan(x) 3 ( )<br />
atan2(y,x) 3 ( )<br />
sinh(x) 1 ( )<br />
cosh(x) 1 ( )<br />
tanh(x) 1 ( )<br />
asinh(x) 2 ( )<br />
acosh(x) 2 ( )<br />
atanh(x) 2 (<br />
pow(x,y) 2 (<br />
erf(x) 2 (<br />
erfc(x) 6 (<br />
lgamma(x) 4 ( ... -2.2637;<br />
tgamma(x) 7 (<br />
fma(x,y,z) 0 (IEEE-754<br />
frexp(x,exp) 0 (<br />
ldexp(x,exp) 0 (<br />
) 大<br />
于 round()<br />
个 8<br />
而 rint()<br />
大 数 学 标 准 库 函 数 及 其 最 大 ULP<br />
<strong>CUDA</strong> 误 差 表 示 为 正 确 舍 入 的 双 精 度 结 果 和 大 最<br />
ulp 返 回 的 结 果 之 间 以 数 函<br />
大 最 大 ulp<br />
62 <strong>CUDA</strong> 编<br />
) 围 范<br />
) 围 范<br />
) 围 范<br />
2.0 南 , 版 本 指 程<br />
) 围 范<br />
距 -11.0001<br />
) 围 范<br />
) 围 范<br />
) 围 范
后<br />
后<br />
后<br />
后<br />
程 指 南 , 版<br />
和<br />
它 y),<br />
前<br />
。<br />
所 列 函 数 的 精 确 度 较 低 但 速 度 节<br />
范 全 围 scalbn(x,n) 0 (<br />
scalbln(x,l) 0 ( )<br />
logb(x) 0 ( )<br />
ilogb(x) 0 ( )<br />
fmod(x,y) 0 ( )<br />
remainder(x,y) 0 ( )<br />
remquo(x,y,iptr) 0 ( )<br />
modf(x,iptr) 0 ( )<br />
fdim(x,y) 0 ( )<br />
trunc(x) 0 ( )<br />
round(x) 0 ( )<br />
rint(x) 0 ( )<br />
nearbyint(x) 0 ( )<br />
ceil(x) 0 ( )<br />
floor(x) 0 ( )<br />
lrint(x) 0 ( )<br />
lround(x) 0 ( )<br />
llrint(x) 0 ( )<br />
llround(x) 0 ( )<br />
signbit(x)<br />
N/A<br />
isinf(x)<br />
N/A<br />
isnan(x)<br />
N/A<br />
isfinite(x)<br />
N/A<br />
copysign(x,y)<br />
N/A<br />
fmin(x,y)<br />
N/A<br />
fmax(x,y)<br />
N/A<br />
fabs(x)<br />
N/A<br />
nan(cptr)<br />
N/A<br />
nextafter(x,y)<br />
N/A<br />
) 围 范<br />
B.1.3<br />
整 型 函 数<br />
<strong>CUDA</strong> 运<br />
y)<br />
B.2 设 备 运 行 时 组 件<br />
们 可 映 射 到 设 备 上 的 一 条 指 令<br />
min(x, 库 支 持 整 型 时 行<br />
max(x,<br />
( 如 __sinf(x))。 缀<br />
用 _rn<br />
<strong>CUDA</strong> 编<br />
型 强 制 转 换 函 数 直 接 对 一 个 参<br />
63<br />
__ 的 版 本 ; 它 们 具 有 相 同 的 名 称 , 另 外 加 上 快 更<br />
B.1 节 列 举 了 仅 在 设 备 代 码 中 支 持 的 内 建 函 数 。 这 些 函 数 中 包 括 第 一 这<br />
__int_as_float(0xC0000000) 等<br />
等<br />
_ru 用 使<br />
舍 入 到 最 近 的 偶 数 模 式 操 作 ;<br />
上 正 ; 使<br />
的 函 数 将 使 用 向 下 舍 入 ( 向 负 无 穷 大 ) 模 式 。 不 同 于 将 一 种 类 型 转 换 为 另 一 种 类 型 的 类 型 转 换 函 数 ( 类 数 执 行 类 型 强 制 转 换 , 而 保 留 其 值 不 变 。 例 如 : 缀<br />
_rz 用 使<br />
的 函 数 将 使 用 向 零 方 向 舍 入 模 式 操 作 ; 缀<br />
本 2.0<br />
_rz 用 使<br />
如 _int2float_rn),<br />
于 -2,__float_as_int(1.0f)<br />
于 0x3f800000。
B.2.1<br />
单 精 度 浮 点 函 数<br />
__fadd_rn() __fmul_rn() FMAD 和 映 射 为 加 法 和 法 作 且 译 不 把 们 入 。 此 相 比 ,“*” 和 “+” 运 算 符 生 成 的 加 法 和 乘 法 一 般 都 将 被 并 入 FMAD。<br />
_fdividef(x, y) 2 126 < y < 2 128 ,__fdivedef(x, y)<br />
B-1 2<br />
普 通 浮 点 除 法 和 具 有 相 同 精 度 , 但 在 时 为 0,<br />
126 < y < 2 128 x<br />
__ fdivedf(x, y) 0<br />
而 普 通 除 法 将 在 表 列 举 的 精 确 度 内 提 供 正 确 。 同 样 , 在 时 , 如 果 是 无 穷 大 ,<br />
操 编 器 会<br />
__[u]mul24(x, y) x y 24 32 。x<br />
y 8<br />
他 并 中 与<br />
NaN(<br />
__[u]mulhi(x, y) x y 64 32<br />
的 结 果 ), 而 普 通 除 法 将 返 回 无 穷 大 。<br />
__[u]mul64hi(x, y) 64 x y 128 个 最 低 有 效 的 乘 积 , 提 供 个 最 低 有 效 位 的 结 果 和 的 个 最 高 有 效 位 将 被 忽 略 。 将<br />
64<br />
得<br />
__saturate(x)<br />
到<br />
x<br />
结<br />
0<br />
果<br />
x<br />
无<br />
1<br />
__[u]sad(x,<br />
穷<br />
y, z<br />
大<br />
x y<br />
以<br />
, 提 供 位 结 果 中 的 个 最 高 有 效 位 计 算 位 整 型 参 数 和 的 乘 积 , 提 供 位 结 果 中 的 个 最 高 有 效 位 。 将 在 小 于 时 0, 在 大 于 时 返 回 1, 否 则 返 回 x。 计<br />
__clz(x) x 31 0 0 32<br />
0<br />
算 整 型 参 数 和 的 乘 积<br />
型 参 数 z)(<br />
__clzll(x) 64 x 63 0 0 64<br />
整 型 参 数 与 的 差 绝 对 值 之 和 。<br />
0 从 最 高 有 效 位 ( 即 第 位 ) 开 始 的 连 续 位 的 数 量 , 介 于 和 之 间 ( 包<br />
__ffs(x) x x<br />
括 和 32)。 和<br />
0,_ffs()<br />
绝<br />
Linux<br />
对 差 之 和 ) 返 回 整 位 ( 即 第 ) 开 始 的 连 续 的 数 量 , 介 于 和 之 间 ( 包 括 和 64)。<br />
整 型 参 数 中 第 一 个 ( 最 低 有 效 ) 位 组 的 位 置 。 最 低 有 效 位 是 位 置 1。 如 果 为 将 返 回 0。 请 注 意 , 此 函 数 等 同 于 函 数 ffs。<br />
__ffsll(x) x x<br />
0,__ffsll() Linux 从 高<br />
一 个 ( 最 低 有 效 ) 位 组 的 位 置 。 最 低 有 效 位 是 位 置 1。 如 果 为 将 返 回 0。 请 注 意 , 此 函 数 等 同 于 函 数 ffsll。<br />
B-3 <strong>CUDA</strong><br />
__fadd_[rn,rz](x,y)<br />
IEEE<br />
__fmul_[rn,rz](x,y)<br />
IEEE<br />
__fdividef(x,y)<br />
表 运 行 时 库 支 持 的 单 精 度 浮 点 建 函 数 及 其 误 差 范 围<br />
y [2<br />
返 回 位 整 型 参 数 中 的 第 误 差 范 围<br />
符 合 -126 , 2 126 ] ulp 2.<br />
__expf(x)<br />
ulp<br />
2 + floor(abs(1.16 * 区 间 内 , 则 最 大 误 差 为 __exp10f(x)<br />
ulp<br />
2 + floor(abs(2.95 *<br />
函 数<br />
为<br />
x))。<br />
__logf(x)<br />
x [0.5, 2] 2 -21.41, ulp<br />
__log2f(x)<br />
x [0.5, 2] 2 ulp<br />
则 最 大<br />
最 大 误 差 -22,<br />
__log10f(x)<br />
x [0.5, 2] 2 ulp<br />
2。 否 -24,<br />
__sinf(x) x [-π, π] 2<br />
否 则 最 大 误 差 为 3。<br />
-21.41<br />
__cosf(x) x [-π, π] 2 -21.19<br />
__sincosf(x,sptr,cptr) sinf(x) cosf(x)<br />
__tanf(x)<br />
__sinf(x) * (1 /<br />
如 果 在 区 间 内 , 则 最 大 绝 对 误 差 为 , 否 则 更 大 。<br />
相 同 。 误 差 为 3。<br />
__powf(x, y)<br />
exp2f(y * 下 实 现 :<br />
__log2f(x))。<br />
__mul24(x,y)<br />
N/A<br />
__umul24(x,y)<br />
__cosf(x))。<br />
__mulhi(x,y)<br />
N/A<br />
以 自 承 继 和<br />
__umulhi(x,y)<br />
64 <strong>CUDA</strong> 2.0 本 版 , 南 指 程 编<br />
与
和<br />
映<br />
位<br />
位<br />
程 指 南 , 版<br />
的<br />
的<br />
的<br />
的 位 数 。<br />
算 。 与 此 相 比 ,“*” 运<br />
围<br />
__int_as_float(x)<br />
N/A<br />
__float_as_int(x)<br />
N/A<br />
__saturate(x)<br />
N/A<br />
__sad(x,y,z)<br />
__usad(x,y,z)<br />
N/A<br />
__clz(x)<br />
N/A<br />
__ffs(x)<br />
N/A<br />
__float2int_[rn,rz,ru,rd] N/A<br />
__float2uint_[rn,rz,ru,rd] N/A<br />
__int2float_[rn,rz,ru,rd] N/A<br />
__uint2float_[rn,rz,ru,rd] N/A<br />
B.2.2<br />
双 精 度 浮 点 函 数<br />
_dadd_rn()<br />
<strong>CUDA</strong> 运<br />
__dadd_[rn,rz,ru,rd](x,y)<br />
__dmul_[rn,rz,ru,rd](x,y)<br />
__fma_[rn,rz,ru,rd](x,y,z)<br />
__double2float_[rn,rz](x)<br />
__double2int_[rn,rz,ru,rd](x)<br />
__double2uint_[rn,rz,ru,rd](x)<br />
__double2ll_[rn,rz,ru,rd](x)<br />
__double2ull_[rn,rz,ru,rd](x)<br />
__int2double_rn(x)<br />
__uint2double_rn(x)<br />
__ll2double_[rn,rz,ru,rd](x)<br />
__ull2double_[rn,rz,ru,rd](x)<br />
__double_as_longlong(x)<br />
__longlong_as_double(x)<br />
__double2hiint(x)<br />
__double2loint(x)<br />
__hiloint2double(x, ys)<br />
函 数<br />
运 行 时 库 支 持 的 双 精 度 浮 点<br />
IEEE-compliant.<br />
IEEE-compliant.<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
N/A<br />
IEEE<br />
时 库 支 持 的 双 精 度 浮 点 内 建 围 函 数 及 其 误 差 范 误 差 范 围 符 合 行 运<br />
_dmul_rn()<br />
FMAD 加 法 和 乘 法 运 算 , 且 编 译 器 不 会 把 他 们 并 入 为 射<br />
“+” 运 算 符 生 成 的 加 法 和 乘 法 一 般 都 将 被 并 和<br />
入 FMAD。<br />
表 B-4.<br />
B.2.3<br />
整 型 函 数<br />
_popc(x) 返<br />
_popcll(x) 返<br />
位 数<br />
整 型 参<br />
二 进 制 表 示 中 设 置<br />
数 x<br />
为 1<br />
<strong>CUDA</strong> 编<br />
65<br />
64 在 回<br />
32 在 回<br />
x 参 数 型 整<br />
1 制 表 示 中 设 置 为 进 二<br />
本 2.0
位<br />
位<br />
位<br />
处<br />
位<br />
或<br />
或<br />
。<br />
- val), 并<br />
附 录 C 原 子 函 数<br />
更 高 的 设 备 可 用<br />
C.1 数 学 函 数<br />
1.1 函 数 仅 可 用 于 设 备 函 数 之 中 , 仅 对 计 算 能 力 为 子 原<br />
C.1.1<br />
atomicAdd()<br />
64 共 享 存 储 器 和 作 操<br />
1.2 原 子 函 数 只 能 用 于 计 算 能 力 为 的 字<br />
int atomicAdd(int* address, int val);<br />
unsigned int atomicAdd(unsigned int* address,<br />
unsigned int val);<br />
unsigned long long int atomicAdd(unsigned long long int* address,<br />
unsigned long long int val);<br />
处<br />
位<br />
位<br />
高 的 设 备 。 更<br />
+ val), 并<br />
将 结 果 存 储<br />
计<br />
C.1.2<br />
atomicSub()<br />
int atomicSub(int* address, int val);<br />
unsigned int atomicSub(unsigned int* address,<br />
unsigned int val);<br />
。 字<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
的 32<br />
或 64<br />
字 old,<br />
算 (old<br />
存 储 器 的 同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 回 old。 在<br />
64 全 局 存 储 器 支 持 有 只<br />
C.1.3<br />
atomicExch()<br />
int atomicExch(int* address, int val);<br />
unsigned int atomicExch(unsigned int* address,<br />
计<br />
unsigned int val);<br />
unsigned long long int atomicExch(unsigned long long int* address,<br />
unsigned long long int val);<br />
float atomicExch(float* address, float val);<br />
处<br />
位<br />
位<br />
存<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
的 32<br />
字 old,<br />
算 (old<br />
将 结 果 存 储 在 存 储 器 的<br />
同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 回 old。<br />
储 在 存 储 器 的 同 一 地<br />
并<br />
C.1.4<br />
atomicMin()<br />
66 <strong>CUDA</strong> 编<br />
读 取 位 于 全 局 或 共 享 存 储 器 中 地<br />
int atomicMin(int* address, int val);<br />
unsigned int atomicMin(unsigned int* address,<br />
unsigned int val);<br />
址 address<br />
的 32<br />
或 64<br />
字 old,<br />
将 val<br />
中 。 这 两 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 回 old。 址<br />
64 全 局 存 储 器 支 持 有 只<br />
。 字<br />
2.0 南 , 版 本 指 程
位<br />
程 指 南 , 版<br />
处<br />
位<br />
计<br />
计<br />
计<br />
和<br />
和<br />
的<br />
的<br />
>= val) ? 0 : (old+1)),<br />
& val), 并<br />
C.1.5<br />
atomicMax()<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
int atomicMax(int* address, int val);<br />
unsigned int atomicMax(unsigned int* address,<br />
unsigned int val);<br />
位 处<br />
的 32<br />
字 old,<br />
算 old<br />
val<br />
存 储 器 的 同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 回 old。 在<br />
最 小 值 , 并 将 结 果 存 储<br />
C.1.6<br />
atomicInc()<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
的 32<br />
字 old,<br />
unsigned int atomicInc(unsigned int* address,<br />
unsigned int val);<br />
位 处<br />
算 old<br />
val<br />
最 大 值 , 并 将 结 果 存 储<br />
C.1.7<br />
atomicDec()<br />
存 储 器 的 同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 回 old。 在<br />
unsigned int atomicDec(unsigned int* address,<br />
unsigned int val);<br />
位 处<br />
val : (old-1)), 并<br />
== 0) | (old > val)) ?<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
的 32<br />
字 old,<br />
算 ((old<br />
将 结 果 存 储 在 存 储 器 的 同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 回 old。 并<br />
C.1.8 atomicCAS()<br />
int atomicCAS(int* address, int compare, int val);<br />
unsigned int atomicCAS(unsigned int* address,<br />
unsigned int compare,<br />
unsigned int val);<br />
unsigned long long int atomicCAS(unsigned long long int* address,<br />
unsigned long long int compare,<br />
unsigned long long int val);<br />
位 位 处<br />
将 结 果 存 储 在 存 储 器 的 同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 计<br />
== compare ? val :<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
的 32<br />
字 old,<br />
算 (((old<br />
回 old。 返<br />
C.2 位 逻 辑 函 数<br />
计<br />
比<br />
<strong>CUDA</strong> 编<br />
67<br />
将 结 果 存 储 在 存 储 器 的 同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 计<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
的 32<br />
或 64<br />
字 old,<br />
算 (old<br />
C.2.1<br />
atomicAnd()<br />
并 较 并 交 换 )。<br />
old),<br />
结 果 存 储 在 存 储 器 的 同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 回 old( 将<br />
64 全 局 存 储 器 支 持 有 只<br />
。 字<br />
int atomicAnd(int* address, int val);<br />
unsigned int atomicAnd(unsigned int* address,<br />
unsigned int val);<br />
位 处<br />
算 (old<br />
本 2.0<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
的 32<br />
字 old,<br />
回 old。
计<br />
计<br />
| val), 并<br />
^ val), 并<br />
C.2.2<br />
atomicOr()<br />
int atomicOr(int* address, int val);<br />
unsigned int atomicOr(unsigned int* address,<br />
unsigned int val);<br />
位 处<br />
C.2.3<br />
atomicXor()<br />
int atomicXor(int* address, int val);<br />
unsigned int atomicXor(unsigned int* address,<br />
unsigned int val);<br />
位 处<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
的 32<br />
字 old,<br />
算 (old<br />
器 的 同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 回 old。 储<br />
将 结 果 存 储 在 存<br />
将 结 果 存 储 在 存<br />
器 的 同 一 地 址 中 。 这 三 项 操 作 在 一 次 原 子 事 务 中 执 行 。 该 函 数 将 返 回 old。 储<br />
address 位 于 全 局 或 共 享 存 储 器 中 地 址 取 读<br />
的 32<br />
字 old,<br />
算 (old<br />
68 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程
≤<br />
寻<br />
的<br />
×<br />
是<br />
×<br />
是<br />
节<br />
个<br />
个<br />
它<br />
:<br />
和<br />
展<br />
寻<br />
,x、y<br />
,x 将<br />
=<br />
、j = floor( y)、k floor(z)。 =<br />
,N =4。<br />
包<br />
即<br />
= Nxˆ、y = Myˆ、z = Lzˆ。<br />
个<br />
的<br />
1.0]( 请<br />
的<br />
进<br />
节<br />
拾 取 < 替 行<br />
)。<br />
的<br />
×<br />
个 第<br />
。x、y、z 继<br />
附 录 D 纹 理 拾 取<br />
4.3.4 节<br />
定 到 纹 理 参 考 的 纹 理 表 示 为 数 组 T, 包 含 针 对 一 维 纹 理 绑<br />
4.4.3 录 提 供 了 用 于 根 据 纹 理 参 考 的 不 同 属 性 计 算 第 附 本<br />
。<br />
的 N<br />
texel,<br />
N 对 二 维 纹 理 的 针 者<br />
M<br />
<br />
<br />
< 0,x 将<br />
效 寻 址 范 围 内 , 之 后 才 能 用 于 寻 归 一 化 的 有<br />
其<br />
绍 的 纹 理 函 数 的 返 回 值 的 公 式 ( 请 参 见 或 介<br />
T。 寻 址 模 式 指 定 了 如 何 将 超 出 范 围 的 纹 理 址<br />
= x-floor(x),floor(x) 是<br />
texel, 或 )。<br />
标 映 射 到 有 效 范 围 内 。 如 坐<br />
N 对 三 维 纹 理 的 针 者<br />
M<br />
L<br />
texel。<br />
x、y 用 纹 理 坐 标 使 将<br />
z<br />
T 坐 标 必 须 位 于 理 纹<br />
如<br />
有 效 寻 址 范 围 内<br />
果 x<br />
x 一 化 的 , 则 仅 支 持 调 整 寻 址 模 式 , 如 果 归 非<br />
x 将 则 0,<br />
为 0, 换<br />
大 整 最<br />
N 果 如<br />
则 替 换 为 N-1。 x,<br />
果 x<br />
和<br />
、yˆ 和 是<br />
在 clamp<br />
x 式 内 , 如 果 模 址<br />
换 为 0, 如 果 1≤ x, 则 替 换 替<br />
为 1-1/N;<br />
D.1 最 近 点 采 样<br />
。 在 下 面 的 内 容 中 数<br />
在 wrap<br />
址 模 式 中<br />
替 换 为 frac(x), 被<br />
中 frac(x)<br />
x 于 大 不<br />
<br />
z<br />
T 一 化 的 纹 理 坐 标 , 已 重 新 映 射 到 归 非<br />
对<br />
y) =<br />
j]<br />
xˆ 归 一 化 纹 理 坐 标 自 承<br />
zˆ,<br />
x<br />
对<br />
y, z) =<br />
j, k]<br />
= floor(x)<br />
对 于 整 型 纹 理 来 说 , 纹 理 拾 取 的 返 回 值 可 重 新 映 射<br />
这 种 过 滤 模 式 中 , 纹 理 拾 取 返 回 的 值 如 下 : 在<br />
tex(x) 一 维 纹 理 是 于 对<br />
T[i]<br />
参 见<br />
i 中 其<br />
tex(x, 维 纹 理 是 二 于<br />
T[i,<br />
图 F-1<br />
示 了 一 维 纹 理 的 最 近 点 采 样<br />
tex(x, 维 纹 理 是 三 于<br />
T[i,<br />
第 4.3.4.1<br />
到 [0.0,<br />
<strong>CUDA</strong> 编<br />
69<br />
的 一 维 纹 理 的 最 近 点 采 样 包<br />
包 含<br />
含 4<br />
texel<br />
2.0 南 , 版 本 指 程<br />
图 F-1.
展<br />
展<br />
位<br />
= 4。 位<br />
,N<br />
值<br />
β<br />
或<br />
的<br />
D.2 线 性 过 滤<br />
对<br />
<br />
<br />
+1, j +1]<br />
理 纹 维 一 于<br />
=<br />
种 仅 对 浮 点 纹 理 可 用 的 过 滤 模 式 中 , 纹 理 拾 取 的 返 回 值 如 下<br />
(1−α)T[i] +αT[i +1]<br />
β 这 在<br />
y) = (1−α )(1−<br />
j] +α<br />
+1, j] + (1−α)βT[i, j +1] +αβT[i<br />
:<br />
j = 中 其<br />
k =<br />
yB ) , β<br />
) , γ<br />
yB ) , yB =<br />
) , zB =<br />
0.5; −<br />
0.5。 −<br />
i = :<br />
tex(x)<br />
对 于 三 维 纹 理 是<br />
) , α<br />
) , xB =<br />
− 0.5;<br />
tex(x, 二 维 纹 理 是 于 对<br />
)T[i,<br />
(1−<br />
)T[i<br />
floor(xB<br />
= frac(xB<br />
x<br />
floor(<br />
= frac(<br />
y<br />
9 γ 存 储 在 和 α、β<br />
8 点 格 式 中 , 有 定 的<br />
fractional<br />
。<br />
floor(zB<br />
= frac(zB<br />
z<br />
图 F-2<br />
示 了 一 维 纹 理 的 最 近 点 采 样<br />
D.3 表 查 找<br />
压<br />
个<br />
的<br />
且<br />
可<br />
=<br />
−1]。<br />
, 其<br />
处<br />
R] 区<br />
图 F-2.<br />
压 缩 寻 址 模 式 中 有<br />
的 一 维 纹 理<br />
纹 理 滤 的 线 性 过 70 <strong>CUDA</strong><br />
来<br />
编<br />
维 纹 理 。 一<br />
有 压 缩 寻 址 模 式 中 有 4<br />
Texel<br />
滤<br />
现 为 示 了 利 用 纹 理 过 滤 来 实 现 表 查 找 , 其 实<br />
TL(x) 找 函 数 查 表<br />
= T[0]<br />
TL(R)<br />
T[N<br />
中 x<br />
于 [0,<br />
自 N=4<br />
TL(0) , 这 样 即 可 确 保 内 间<br />
R=1,<br />
图 F-3<br />
2.0 南 , 版 本 指 程<br />
中 R=4
程 指 南 , 版<br />
使 用 线 性 过 滤 的 一 维 表 查 找<br />
图 F-3.<br />
<strong>CUDA</strong> 编<br />
71<br />
本 2.0
不 设<br />
、Geforce、Tesla 和<br />
不<br />
都<br />
伟 峰 先 生 对 本 指 南 中 文 版 译 稿 全 文 进 行 了 审 校 , 在 此 表 示 衷 心 的 感 谢 。 刘<br />
<strong>NVIDIA</strong> Corporation 专<br />
Corporation 的<br />
。<strong>NVIDIA</strong> 注 意 : 样 ” 提 供 对 特 定 目 的 的 适 用 性 Corporation 的<br />
规 范 、 参 考 设 计 、 文 件 、 绘 图 、 诊 断 程 序 、 列 表 和 其 他 文 档 ( 统 称 为 “ 材 料 ”) 均 按 “ 原 对 此 材 料 提 供 任 何 明 示 或 暗 示 的 保 证 和 担 保 , 不 保 证 材 料 的 无 侵 害 性 、 适 销 性 或 针 计<br />
对<br />
NVDIA 有 所<br />
<strong>NVIDIA</strong>、<strong>NVIDIA</strong> 徽<br />
Corporation 的<br />
但 <strong>NVIDIA</strong><br />
公 司 或 产 品 名 称 可 能 是 其 对 应 公 司 的 商 标 。<br />
<strong>NVIDIA</strong><br />
们 尽 可 能 保 证 信 息 的 准 确 和 可 靠 。 为 使 用 此 类 信 息 的 后 果 承 担 责 任 , 也 为 使 用 此 类 信 息 可 能 导 致 的 侵 害 第 三 方 专 利 或 其 他 权 利 的 后 果 负 责 。 本 材 料 未 通 过 任 何 隐 含 的 方 式 或 其 他 方 式 授 予 利 或 权 利 权 的 许 可 本 文 档 提 到 的 规 范 可 能 随 时 更 改 , 恕 不 另 行 通 知 。 本 文 档 提 供 。<br />
是 最 新 内 容 , 取 代 之 前 提 供 的 所 有 信 息 。 若 无 明 确 书 面 许 可 , 不 得 我<br />
品 用 作 生 命 保 障 设 备 或 系 统 的 关 键 组 件 。<br />
商 标 产 的<br />
将 <strong>NVIDIA</strong><br />
© 2007-2008 <strong>NVIDIA</strong> Corporation. 保<br />
:Scalable Parallel Programming with <strong>CUDA</strong>, in ACM<br />
Queue, VOL 6, No. 2 (March/April 2008), © ACM, 2008. http://mags.acm.org/queue/20080304/?u1=texterity"<br />
版 权 留 所 有 权 利 。 本 文 档 整 合 了 早 先 一 份 资 料 的 部 分 内 容 致 谢<br />
标<br />
Quadro<br />
是 <strong>NVIDIA</strong><br />
商 标 或 注 册 商 标 。 其 他<br />
<strong>NVIDIA</strong> Corporation<br />
72 <strong>CUDA</strong> 编<br />
2.0 南 , 版 本 指 程