CUDA 结果使用非常大的数组返回垃圾,但不报告错误

2023-11-24

我正在创建一个测试程序,它将创建一个设备和一个大小的主机数组n然后启动一个内核来创建n将常量值 0.95f 分配给设备数组中的每个位置的线程。完成后,设备阵列将复制到主机阵列,并对所有条目进行总计并显示最终总计。

下面的程序似乎对于高达 6000 万个浮点数的数组大小工作得很好,并且很快返回正确的结果,但是当达到 7000 万个浮点数时,程序似乎挂起一段时间,并最终返回总数的 NAN 结果。在 6000 万次运行后检查主机阵列显示它已正确填充了 0.95f,但在 7000 万次运行后检查它显示它已填充了 NAN。据我所知,没有任何 CUDA 调用返回错误。

我使用的是 2GB GT640m(计算 3.0),最大块大小为 1024,最大网格尺寸为 2147483647。

我确信有更好的方法可以实现类似的目标,并且我想听到建议。但我也想了解这里出了什么问题,以便我可以从中学习。

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>
#include <fstream>

void cudaErrorHandler(cudaError_t status)
{
    // Cuda call returned an error, just print error for now
    if(status != cudaSuccess)
    {
        printf("Error");
    }
}

__global__ void addKernel(float* _Results, int _TotalCombinations)
{
    // Get thread Id
    unsigned int Id = (blockDim.x * blockDim.y * blockIdx.x) + (blockDim.x * threadIdx.y) + threadIdx.x;

    //If the Id is within simulation range, log it
    if(Id < _TotalCombinations)
    {
        _Results[Id] = 0.95f;
    }
}

#define BLOCK_DIM_X 32
#define BLOCK_DIM_Y 32
#define BLOCK_SIZE BLOCK_DIM_X * BLOCK_DIM_Y // Statc block size of 32*32 (1024)
#define CUDA_CALL(x) cudaErrorHandler(x)

int main()
{
    // The number of simulations to run
    unsigned int totalCombinations = 45000000;

    int gridsize = 1;

    // Work out how many blocks of size 1024 are required to perform all of totalCombinations
    for(unsigned int totalsize = gridsize * BLOCK_SIZE; totalsize < totalCombinations; 
        gridsize++, totalsize = gridsize * BLOCK_SIZE)
        ;

    // Allocate host memory
    float* host_results = new float[totalCombinations];
    memset(host_results, 0, sizeof(float) * totalCombinations);
    float *dev_results = 0;

    cudaSetDevice(0);

    // Allocate device memory
    CUDA_CALL(cudaMalloc((void**)&dev_results, totalCombinations * sizeof(float)));

    dim3 grid, block;

    block = dim3(BLOCK_DIM_X, BLOCK_DIM_Y);

    grid = dim3(gridsize);

    // Launch kernel
    addKernel<<<gridsize, block>>>(dev_results, totalCombinations);

    // Wait for synchronize
    CUDA_CALL(cudaDeviceSynchronize());

    // Copy device data back to host
    CUDA_CALL(cudaMemcpy(host_results, dev_results, totalCombinations * sizeof(float), cudaMemcpyDeviceToHost));

    double total = 0.0;

    // Total the results in the host array
    for(unsigned int i = 0; i < totalCombinations; i++)
        total+=host_results[i];

    // Print results to screen
    printf("Total %f\n", total);

    delete[] host_results;

    return 0;
}

正如您所发现的,您的错误处理方法不起作用。下面我粘贴了您的代码版本,其中包含我经常使用的错误检查方法。在您的故障点处无法正常工作的原因是您的网格大小(您正在启动一维网格)超过了 X 维度中的最大网格大小(默认情况下为 65535,即计算能力高达 2.x)。如果你想利用更大的网格尺寸(2^31 -1 是计算能力 3.0 的限制),你需要使用-arch=sm_30转变。

这里仅供参考的是您的代码版本,其中显示了我经常使用的错误检查方法。

#include <stdio.h>
#include <fstream>


#define cudaCheckErrors(msg) \
    do { \
        cudaError_t __err = cudaGetLastError(); \
        if (__err != cudaSuccess) { \
            fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \
                msg, cudaGetErrorString(__err), \
                __FILE__, __LINE__); \
            fprintf(stderr, "*** FAILED - ABORTING\n"); \
            exit(1); \
        } \
    } while (0)

__global__ void addKernel(float* _Results, int _TotalCombinations)
{
    // Get thread Id
    unsigned int Id = (blockDim.x * blockDim.y * blockIdx.x) + (blockDim.x * threadIdx.y) + threadIdx.x;

    //If the Id is within simulation range, log it
    if(Id < _TotalCombinations)
    {
        _Results[Id] = 0.95f;
    }
}

#define BLOCK_DIM_X 32
#define BLOCK_DIM_Y 32
#define BLOCK_SIZE BLOCK_DIM_X * BLOCK_DIM_Y // Statc block size of 32*32 (1024)

int main()
{
    // The number of simulations to run
    unsigned int totalCombinations = 65000000;

    int gridsize = 1;

    // Work out how many blocks of size 1024 are required to perform all of totalCombinations
    for(unsigned int totalsize = gridsize * BLOCK_SIZE; totalsize < totalCombinations;
        gridsize++, totalsize = gridsize * BLOCK_SIZE)
        ;
    printf("gridsize = %d, blocksize = %d\n", gridsize, BLOCK_SIZE);
    // Allocate host memory
    float* host_results = new float[totalCombinations];
    memset(host_results, 0, sizeof(float) * totalCombinations);
    float *dev_results = 0;

    cudaSetDevice(0);

    // Allocate device memory
    cudaMalloc((void**)&dev_results, totalCombinations * sizeof(float));
    cudaCheckErrors("cudaMalloc fail");

    dim3 grid, block;

    block = dim3(BLOCK_DIM_X, BLOCK_DIM_Y);

    grid = dim3(gridsize);

    // Launch kernel
    addKernel<<<gridsize, block>>>(dev_results, totalCombinations);
    cudaCheckErrors("kernel fail");
    // Wait for synchronize
    cudaDeviceSynchronize();
    cudaCheckErrors("sync fail");

    // Copy device data back to host
    cudaMemcpy(host_results, dev_results, totalCombinations * sizeof(float), cudaMemcpyDeviceToHost);
    cudaCheckErrors("cudaMemcpy 2 fail");

    double total = 0.0;

    // Total the results in the host array
    for(unsigned int i = 0; i < totalCombinations; i++)
        total+=host_results[i];

    // Print results to screen
    printf("Total %f\n", total);

    delete[] host_results;

    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CUDA 结果使用非常大的数组返回垃圾,但不报告错误 的相关文章

  • 将复选框添加到 UniformGrid

    我正在尝试将复选框动态添加到 wpf 中的统一网格中 但看起来网格没有为它们分配足够的空间 所以它们都有点互相重叠 这就是我将它们添加到后面的代码中的方法 foreach string folder in subfolders PathCh
  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • C# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • linux perf:如何解释和查找热点

    我尝试了linux perf https perf wiki kernel org index php Main Page今天很实用 但在解释其结果时遇到了困难 我习惯了 valgrind 的 callgrind 这当然是与基于采样的 pe
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • Newtonsoft JSON PreserveReferences处理自定义等于用法

    我目前在使用 Newtonsoft Json 时遇到一些问题 我想要的很简单 将要序列化的对象与所有属性和子属性进行比较以确保相等 我现在尝试创建自己的 EqualityComparer 但它仅与父对象的属性进行比较 另外 我尝试编写自己的
  • 获取没有非标准端口的原始 url (C#)

    第一个问题 环境 MVC C AppHarbor Problem 我正在调用 openid 提供商 并根据域生成绝对回调 url 在我的本地机器上 如果我点击的话 效果很好http localhost 12345 login Request
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • 如何返回 json 结果并将 unicode 字符转义为 \u1234

    我正在实现一个返回 json 结果的方法 例如 public JsonResult MethodName Guid key var result ApiHelper GetData key Data is stored in db as v
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 如何衡量两个字符串之间的相似度? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给定两个字符串text1 and text2 public SOMEUSABLERETURNTYPE Compare string t
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • 无法初始化 NVML:几个小时后 Docker 中出现未知错误

    我遇到有趣而奇怪的问题 当我使用 GPU 启动 docker 容器时 它工作正常 并且我看到 docker 中的所有 GPU 然而 几个小时或几天后 我无法在docker中使用GPU 当我做nvidia smi在泊坞窗机器中 我看到这条消息
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • 为什么我无法运行我的 Node.js Express Web 应用程序

    Node js 和 Express 生成器确实非常方便且易于理解 但是 我无法通过运行 c my application root gt DEBUG my application bin www 来启动我的服务器 Windows 似乎不理解
  • 找不到 matplotlib 数据文件

    我是 python 新手 我正在尝试使用 pyinstaller 从 py 脚本创建 exe 但在尝试运行 exe 时出现此错误 无法找到 matplotlib 数据文件 当我在 python 空闲中运行脚本时 我没有收到此错误 我试过了
  • Eclipse CDT Indexer 不能完全识别 c++11

    首先 我了解用于启用 c 11 支持的 std c 11 标志及其放置位置 我已附加 std c 11 to Project gt Properties gt C C Build gt Settings gt Tool Settings g
  • Internet Explorer-10 websocket 中的 IPv6 地址给出语法错误

    我从服务器获取 ipv6 地址 然后我为 websocket 创建 url 我的网址看起来 喜欢 ws xxxx xxxx xxxx xxxx xxxx xxxx 十进制端口 其中 x 十六进制的 0 f 这个网址在 chrome 和 fi
  • $_SERVER["REMOTE_ADDR"] 提供服务器 IP 而不是访问者 IP

    我正在尝试跟踪访问者的 IP 地址 使用时 SERVER REMOTE ADDR 我得到的是服务器的IP地址而不是访问者的IP地址 我在多个位置的多台机器上进行了尝试 它们都产生了完全相同的 IP 是否有一些 PHP 服务器设置可能会影响这
  • Ruby 中的有符号和无符号整数

    像 C 一样 Ruby 是否有有符号和无符号整数 如果有的话 是否意味着 String 类的 length 方法返回有符号整数 因为在 C 整数中 如果未指定则意味着有符号 Ruby 实现整数的方式使得有符号 无符号的区别无关紧要 因为 R
  • 如何排列 TPopupMenu 以使其准确地将自己定位在按钮上方?

    我想要一个按钮上方的弹出菜单 Delphi 包装 Win32 菜单系统的方式似乎排除了底层 Win32 API 提供的每种模式或标志 而这些模式或标志当时并没有出现在 VCL 作者的脑海中 一个这样的例子似乎是TPM BOTTOMALIGN
  • jQuery UI DatePicker - 禁用除每个月的第一天和第 15 天之外的所有日期

    我想禁用此日期选择器上除每月 1 日和 15 日之外的所有日期 我引用了这个已回答的问题 但我只能返回一个日期 我是 javascript 的新手 jQuery UI DatePicker 禁用除每月最后一天之外的所有日期 任何帮助都会很棒
  • Python 中的 3D Dicom 可视化

    我是 3D 图像处理新手 我想知道如何用python查看dicom系列 我尝试使用 matplotlib 和 VTK 在 matplot 中 我无法像使用 volViewer 在 matlab 中查看那样查看体积 关于 VTK 我无法导入
  • 替换 csv 文件中的新行 (\n) 字符 - Spark scala

    为了说明问题 我采取了一个测试集 csv 文件 但在实际情况下 问题必须处理超过 TeraByte 的数据 我有一个 CSV 文件 其中的列用引号括起来 col1 但是当数据导入完成后 一列包含换行符 n 当我想将它们保存为 Hive 表时
  • JQuery 中的条件规则验证

    我在用jQuery 验证 现在我希望只有在满足某些条件时才调用我的规则 即我想要 AppSelectField is hidden 回来false 然后我才调用规则 我的规则如下 function RequestLock validate
  • C++ 在 << 之后使用 stringstream 作为参数

    是否可以编写一个采用字符串流的方法并使其看起来像这样 void method string str void printStringStream StringStream ss method ss str 并且可以这样调用 stringst
  • 白名单和黑名单安全性哪个更好,或两者兼而有之? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我很快就会构建一个网络应用程序 我需要一个安全模型 以便不同的用户可以访问应用程序的不同部分和 或应用程序的特定部分内的不同数据集 我正在争论以下两种实现安全性的方法 白名单 默认情况下
  • 无法从“pytorch_lightning.utilities”导入名称“_TPU_AVAILABLE”

    我正在尝试导入 aitexten 包以在 GPT 2 解决方案上工作 但我遇到了一个错误 ImportError 无法从 pytorch lightning utilities 导入名称 TPU AVAILABLE usr local li
  • 如何向 django 模板中的自定义模板过滤器添加多个参数?

    这是我的自定义过滤器 from django import template register template Library register filter def replace value cherche remplacement
  • 以编程方式创建 Firefox 配置文件

    Question 是否有一种简单的编程方式来创建新的 Firefox 配置文件 nsIToolkitProfileService看起来它可能会起作用但是docs say 从 Gecko 18 开始 Firefox 18 0 Thunderb
  • 我的 javascript 返回此错误: $.ajax 不是函数

    不知道出了什么问题 但我从 chrome 控制台收到此错误 jquery 3 2 1 slim min js 1244 jQuery Deferred exception ajax is not a function TypeError a
  • 检查 int 是否在两个数字之间

    如果你试图找出 int 是否在数字之间 为什么不能这样做 if 10 lt x lt 20 相反 你必须这样做 if 10
  • CherryPy 和并发

    我使用 CherryPy 是为了通过 WSGI 提供 python 应用程序 我尝试对其进行基准测试 但 CherryPy 似乎只能处理 10 个请求 秒 不管我做什么 构建了一个带有 3 秒暂停的简单应用程序 以便准确确定发生了什么 并且
  • CUDA 结果使用非常大的数组返回垃圾,但不报告错误

    我正在创建一个测试程序 它将创建一个设备和一个大小的主机数组n然后启动一个内核来创建n将常量值 0 95f 分配给设备数组中的每个位置的线程 完成后 设备阵列将复制到主机阵列 并对所有条目进行总计并显示最终总计 下面的程序似乎对于高达 60