← 返回测试报告
ENGINEERING REPORT / 2026-08-01

Hashcat 海光 DCU
HIP 后端适配与性能对比

面向 DTK 25.04.2、HIP 6.3.25422 与 gfx936/BW DCU 的 ABI 兼容适配、构建方法、功能验证及 OpenCL 基线对比。

项目目录:/path/to/hashcat 测试节点:计算节点(名称已脱敏) Hashcat:v7.1.2 作者:opensource_community

1. 执行摘要

hashcat v7.1.2 已包含 HIP 后端,但其内置 HIP ABI 与海光 DTK 25.04.2 的 libgalaxyhip.so 存在版本差异,设备初始化流程因而无法完成。本次适配增加显式、可选的 DTK_HIP=1 构建模式,对齐设备属性枚举与 hipDeviceProp_t 布局,并调整 DTK 动态库的退出生命周期。验证结果表明,适配后的 HIP 后端可完成设备枚举、HIPRTC 内核编译、实际任务运行、benchmark 及正常退出。

HIP 设备枚举通过BW / 80 MCU / 64 GB
HIP SHA2-2565.914 GH/s45 秒持续负载
OpenCL SHA2-2565.913 GH/s45 秒持续负载
性能差异< 0.01%可视为相同
核心结论:HIP 适配链路已通过功能验证。在本报告所述 SHA2-256 大密钥空间测试中,HIP 与 OpenCL 的吞吐、功耗、温度和利用率接近。该适配的主要价值在于完善 HIP 可用性并为后续定向优化建立基础;现有数据不足以支持通用性能提升的结论。

2. 测试环境与产物

软件环境

  • Hashcat:v7.1.2
  • DTK:25.04.2
  • HIP:6.3.25422
  • OpenCL:OpenCL 2.1s C-3000-APP (3452.0)
  • 内核:5.10.134-17.1.3.sga8.x86_64
  • 系统:Sugon OS 8.9

硬件环境

  • 测试节点:<compute-node>(名称已脱敏)
  • DCU 名称:BW
  • ISA:gfx936:sramecc+:xnack-
  • 设备类型:HCU
  • 计算单元:80
  • 显存:65520 MB
  • 核心频率:1500 MHz

最终二进制

用途路径大小SHA-256
DTK HIP 适配版hashcat-hip-dtk1,332,656 Bbe0b2201c913828488dfe07ce64eef3f481c97ae4cfe41d4af8ffc1549df1e36
OpenCL 基线版本hashcat-opencl-original1,332,656 Ba25c3b28ad1c980aef71457ff0cc7d367dd0e4165ab2dc6ac9d20fcb48208994

二进制示例路径为 /path/to/hashcat/。OpenCL 基线版本单独保留,以便开展回归验证与性能对比。

3. 兼容性现象与原因分析

3.1 登录节点与计算节点的区别

登录节点未提供 /dev/kfd,因此该环境仅适合检查二进制中的 HIP 符号,不具备设备运行验证条件。进入已分配的 DCU 计算节点后,rocminfohy-smi 与 OpenCL 均可正常识别设备。

rocminfo:
  Name:           gfx936
  Marketing Name: BW
  Device Type:    HCU
  Compute Unit:   80

3.2 适配前的 HIP 初始化现象

./hashcat -II --backend-ignore-cuda --backend-ignore-opencl

hashcat (v7.1.2) starting in backend information mode
hipDeviceGetAttribute(): invalid argument
No devices found/left.

同一环境下 OpenCL 能够识别 BW 设备,可据此排除硬件、任务分配、驱动和设备权限等基础因素,并将分析范围收敛至 hashcat HIP 主机侧 API 兼容层。

3.3 ABI 差异

hashcat 为保持动态加载能力,在 include/ext_hip.h 内复制了 HIP 类型定义,而不是编译时直接依赖系统 HIP 头文件。hashcat v7.1.2 内置定义来自更新的 ROCm ABI;DTK 25.04.2 的 hip_runtime_defines.h 使用不同的旧版布局。

DTK 属性DTK 25.04.2 数值用途
hipDeviceAttributeMaxThreadsPerBlock18最大线程块
hipDeviceAttributeMaxSharedMemoryPerBlock25共享内存
hipDeviceAttributeTotalConstantMemory26常量内存
hipDeviceAttributeWarpSize27Wave/Warp 宽度
hipDeviceAttributeClockRate29设备时钟
hipDeviceAttributeMultiprocessorCount32计算单元数量
hipDeviceAttributeComputeCapabilityMajor/Minor36 / 37计算能力
hipDeviceAttributePciBusId/PciDeviceId39 / 40PCI 地址
hipDeviceAttributeIntegrated42统一内存判断
hipDeviceAttributeKernelExecTimeout79内核超时属性

辅助探测程序还确认 DTK 的 sizeof(hipDeviceProp_t) = 792,关键字段偏移包括:totalGlobalMem=256regsPerBlock=272warpSize=276clockRate=308major=328multiProcessorCount=336gcnArchName=396。这与 hashcat 原定义明显不同。

4. 代码修改说明

实现遵循“默认构建行为保持不变、DTK 适配显式启用”的原则,改动集中在构建入口、HIP 类型定义、设备属性初始化、动态加载与适配说明文档。

步骤 1:增加独立构建开关
src/Makefile

新增 DTK_HIP ?= 0。只有执行 make DTK_HIP=1 时才定义 HC_HIP_DTK,普通构建仍使用原始 ROCm ABI。

DTK_HIP ?= 0

ifeq ($(DTK_HIP),1)
CFLAGS += -DHC_HIP_DTK
endif
步骤 2:对齐 DTK 设备属性枚举
include/ext_hip.h

HC_HIP_DTK 条件分支下显式定义 hashcat 实际使用的 DTK 属性编号。原始完整枚举保留在 #else 分支,不影响默认 ROCm 构建。

步骤 3:对齐 792 字节设备属性结构
include/ext_hip.h

按 DTK 25.04.2 的字段顺序重建 hipDeviceProp_t,保证 hipGetDeviceProperties() 写入的内存布局与 hashcat 读取方式一致,尤其是 regsPerBlockgcnArchName 等字段。

步骤 4:兼容缺失的寄存器属性
src/backend.c

DTK 旧版结构没有 regsPerMultiprocessor 字段,而且属性编号 69 的运行时查询返回 hipErrorInvalidValue。DTK 分支使用已验证可用的 prop.regsPerBlock 作为保守兼容值。

#if defined (HC_HIP_DTK)
device_param->regsPerMultiprocessor = prop.regsPerBlock;
#else
device_param->regsPerMultiprocessor = prop.regsPerMultiprocessor;
#endif
步骤 5:完善诊断日志
src/ext_hip.c

诊断日志同时输出设备编号和属性编号,便于将运行时状态定位到具体 ABI 项;并校正 hipGetDeviceProperties 对应的日志标识。

hipDeviceGetAttribute(dev=0, attrib=69): invalid argument
步骤 6:调整动态库退出生命周期
src/ext_hip.c / src/ext_hiprtc.c

DTK 的 HIP/HIPRTC DSO 注册了 C++ 退出回调。hashcat 提前 dlclose() 后,libstdc++ 在进程退出阶段仍调用这些回调,导致跳转到已卸载地址。DTK 构建因此不提前关闭这两个 DSO,交由操作系统在进程终止时回收。

步骤 7:保留产物和适配文档
.gitignore / docs/dtk-hip-adaptation.md

构建产物不纳入版本控制,并补充构建、验证与版本边界说明;OpenCL 基线版本单独保存,用于回归验证和性能对比。

5. 调试过程与关键转折

  1. 确认二进制包含 HIP:检查到 hipInithipDeviceGetAttributehiprtcCompileProgram 等符号,以及 --backend-ignore-hip 参数。
  2. 排除无卡节点误判:登录节点缺少 /dev/kfd;切换到已分配的计算节点后,DCU 与驱动均正常。
  3. 建立 OpenCL 基线:原始二进制可通过 OpenCL 识别 BW,并完成 MD5 benchmark,证明硬件与 hashcat 核心功能正常。
  4. 增强日志后锁定枚举:首个失败属性从不透明的错误变为 attrib=69,随后使用 DTK 头文件编译探测程序逐项核对数值和结构偏移。
  5. 第一次 ABI 修复:同步属性枚举与结构体后,设备枚举推进到寄存器属性;运行时确认属性 69 不受 DTK 支持。
  6. 寄存器兼容处理:辅助程序显示 prop.regsPerBlock=196608,而属性 69 返回错误,因此采用该值作为保守兼容数据。
  7. HIP 设备枚举成功:hashcat 能显示 HIP 6.3.25422、BW、80 MCU、65520 MB 和 PCI 地址。
  8. HIPRTC 验证:MD5 与 NTLM benchmark 成功,证明 gfx936 的运行时编译、module 加载和 kernel launch 链路可用。
  9. 发现退出阶段 SIGSEGV:计算结果已经输出,但退出码为 139。使用 GDB 定位到 libstdc++ 的 atexit_thread.cc:75,栈顶为无符号的已卸载地址。
  10. 修复 DSO 生命周期:DTK 分支保留 HIP/HIPRTC DSO 到进程退出,随后 benchmark 退出码恢复为 0。
  11. 正确性验证:实际 MD5 字典攻击通过 self-test,并恢复 e11c594e6a2f4eb499cceadfca988595:13LEXON

GDB 关键回溯

Thread 1 "hashcat-hip-dtk" received signal SIGSEGV
0x000015552f2620e0 in ?? ()
#0  0x000015552f2620e0 in ?? ()
#1  (anonymous namespace)::run
    at libstdc++-v3/libsupc++/atexit_thread.cc:75
#2  __run_exit_handlers () from /lib64/libc.so.6
#3  exit () from /lib64/libc.so.6

该回溯与“动态库已卸载,但退出处理器仍保留函数地址”一致。修改 DSO 生命周期后,同一测试正常退出,验证了判断。

6. Git 与编译过程

6.1 Git 建档

为保证适配过程可追溯,可先建立源码基线,再在独立分支记录 DTK HIP 适配变更。以下命令展示一种参考流程。

cd /path/to/hashcat
git init -b dtk-hip-adaptation
git add -A
git commit -m "baseline: import hashcat 7.1.2 source tree"

# 完成修改与验证后
git add .gitignore include/ext_hip.h src/Makefile \
  src/backend.c src/ext_hip.c src/ext_hiprtc.c \
  docs/dtk-hip-adaptation.md
git commit -m "feat: adapt HIP backend for DTK 25.04.2"
提交说明
cb48d9dHashcat v7.1.2 源码树基线
提交标识已脱敏DTK 25.04.2 HIP 后端适配

6.2 编译步骤

构建注意事项:当前 Makefile 的对象文件名不包含预处理宏信息。在普通构建与 DTK_HIP=1 构建之间切换时,应执行 make clean,避免复用 ABI 配置不同的对象文件。
cd /path/to/hashcat

# 保留原始二进制
cp -p hashcat hashcat-opencl-original

# 清理并构建 DTK 专用版本
make clean
make DTK_HIP=1 ENABLE_LTO=0
mv hashcat hashcat-hip-dtk

# 基本检查
./hashcat-hip-dtk --version
sha256sum hashcat-hip-dtk hashcat-opencl-original

ENABLE_LTO=0 用于降低适配调试期间的链接复杂度并保持构建可预测性。核心适配由 DTK_HIP=1 启用。

6.3 在 DCU 节点验证

ssh <compute-node>
cd /path/to/hashcat

# 只启用 HIP
./hashcat-hip-dtk -II \
  --backend-ignore-cuda \
  --backend-ignore-opencl

# 只启用 OpenCL
./hashcat-opencl-original -II \
  --backend-ignore-cuda \
  --backend-ignore-hip

7. 功能与正确性验证

验证项命令/方式结果
HIP 设备枚举-II --backend-ignore-cuda --backend-ignore-opencl通过
HIPRTC 优化内核MD5 benchmark通过
MD5 benchmark-b -m 039342.9 MH/s
NTLM benchmark-b -m 100063283.5 MH/s
Self-testMD5 字典实际攻击通过
破解结果example0.hash + example.dict恢复 13LEXON
资源释放与退出benchmark 后检查进程退出码退出码 0
./hashcat-hip-dtk -m 0 -a 0 example0.hash example.dict \
  --backend-ignore-cuda --backend-ignore-opencl \
  --potfile-disable --restore-disable

Recovered:
e11c594e6a2f4eb499cceadfca988595:13LEXON

该字典测试的最终状态码为 1:输入包含 6494 个哈希,小字典耗尽时恢复其中 1 个。self-test 与目标恢复均成功,因此该状态码反映任务完成条件,而非 HIP 后端异常。

8. HIP 与 OpenCL 性能对比

8.1 测试方法

为了避免短 benchmark 隐藏热稳定和持续调度差异,采用 SHA2-256 的 8 位全字符集暴力攻击,密钥空间为 95^8 = 6,634,204,312,890,625。使用不易命中的目标哈希保证 DCU 持续满载,每个后端运行约 45 秒,并通过 hy-smi 每 2 秒采样功耗、温度和利用率。

# HIP
./hashcat-hip-dtk -m 1400 -a 3 \
  ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff \
  '?a?a?a?a?a?a?a?a' -O -w 3 --runtime 45 \
  --status --status-timer 5 --potfile-disable --restore-disable \
  --backend-ignore-cuda --backend-ignore-opencl

# OpenCL:攻击参数相同,只切换后端和二进制
./hashcat-opencl-original -m 1400 -a 3 \
  ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff \
  '?a?a?a?a?a?a?a?a' -O -w 3 --runtime 45 \
  --status --status-timer 5 --potfile-disable --restore-disable \
  --backend-ignore-cuda --backend-ignore-hip

8.2 核心结果

指标HIPOpenCL解读
平均速度(10 个状态样本)5913.79 MH/s5913.48 MH/sHIP 约 +0.005%,无实际差异
最终稳定速度5914.3 MH/s5913.8 MH/s差异小于 0.01%
速度范围5911.5–5914.35910.4–5914.0波动均很小
满载平均功耗368.8 W369.7 W差 0.9 W,在采样波动内
满载功耗范围365–369 W367–370 W基本一致
平均温度61.0°C61.1°C基本一致
最高温度61°C62°C无显著差异
平均利用率100%100%均达到满载
Host memory8173 MB6132 MBHIP 多使用约 2041 MB
运行结束状态Runtime 到期Runtime 到期均按预期停止

速度可视化

HIP
5913.79 MH/s
OpenCL
5913.48 MH/s

横条按 5914.1 MH/s 归一化。两者肉眼不可区分,符合数值差异低于 0.01% 的结论。

8.3 自动调优与资源差异

调度参数HIPOpenCL
Accel627
Loops10241024
Threads1024256
Vector width11
单次调度时间84.95 ms95.55 ms
Preferred thread multiple6432

两个后端选择了不同的工作组和加速组合,但最终吞吐一致,说明两条路径均能充分利用该 DCU。HIP 的主机内存占用明显更高,是本次测试中最明确的资源差异。

8.4 累计进度为何不直接比较

最终记录的 HIP 进度为 266,757,734,400,OpenCL 为 270,092,206,080。OpenCL 看似高约 1.25%,但其最终状态落在约 46 秒,而 HIP 为约 45 秒;初始化、状态刷新和 runtime 停止边界也不完全相同。因此报告以 hashcat 的 10 个持续速度样本作为主比较依据,而不以累计进度得出性能结论。

9. 结论、建议与已知限制

可用性

HIP 设备枚举、HIPRTC、内核加载、实际破解和正常退出均已通过,最小适配目标完成。

性能

在本次 SHA2-256 测试中,HIP 与 OpenCL 均约为 5.914 GH/s,差异不足 0.01%;当前数据未体现显著性能差异。

应用建议

在扩大算法覆盖和稳定性验证前,OpenCL 可作为现有基线;HIP 版本适用于功能验证及后续 gfx936 定向优化。

已知限制

后续建议

  1. 按常用工作负载扩展测试:-m 1000-m 10900-m 22000-m 3200
  2. 对 HIP 和 OpenCL 分别执行 1–4 小时稳定性测试,监控温度、功耗、驱动日志和错误计数。
  3. 为 DTK ABI 增加自动化探测或编译期断言,避免 DTK 升级后静默使用错误布局。
  4. 如果目标是获得性能提升,应进一步分析 HIPRTC 编译参数、寄存器占用、wavefront 行为和专用 tuning,而不是仅切换后端。

10. 附录:复现与审计命令

查看代码变更

cd /path/to/hashcat
git status
git log --oneline --decorate -5
git show --stat 7ef6f77
git show 7ef6f77

重新构建

make clean
make DTK_HIP=1 ENABLE_LTO=0
mv hashcat hashcat-hip-dtk

基本验证

ssh <compute-node>
cd /path/to/hashcat

./hashcat-hip-dtk -II --backend-ignore-cuda --backend-ignore-opencl
./hashcat-hip-dtk -b -m 0 --backend-ignore-cuda --backend-ignore-opencl --runtime 10
./hashcat-hip-dtk -b -m 1000 --backend-ignore-cuda --backend-ignore-opencl --runtime 10

关键文件索引

文件作用
src/MakefileDTK_HIP=1 构建入口
include/ext_hip.hDTK 枚举与结构体 ABI
src/backend.c设备属性初始化兼容
src/ext_hip.cHIP 动态加载、日志和 DSO 生命周期
src/ext_hiprtc.cHIPRTC DSO 生命周期
docs/dtk-hip-adaptation.md仓库内简要适配记录