CUDA 上的块间屏障

2023-11-30

我想在 CUDA 上实现块间屏障,但遇到了严重的问题。

我不明白为什么它不起作用。

#include <iostream>
#include <cstdlib>
#include <ctime>

#define SIZE 10000000
#define BLOCKS 100 

using namespace std;

struct Barrier {
    int *count;

    __device__ void wait() {
        atomicSub(count, 1);
        while(*count)
            ;
    }

    Barrier() {
        int blocks = BLOCKS;
        cudaMalloc((void**) &count, sizeof(int));
        cudaMemcpy(count, &blocks, sizeof(int), cudaMemcpyHostToDevice);
    }

    ~Barrier() {
        cudaFree(count);
    }
};


__global__ void sum(int* vec, int* cache, int *sum, Barrier barrier)
{
    int tid = blockIdx.x;

    int temp = 0;
    while(tid < SIZE) {
        temp += vec[tid];
        tid += gridDim.x;
    }

    cache[blockIdx.x] = temp;

    barrier.wait();

    if(blockIdx.x == 0) {
        for(int i = 0 ; i < BLOCKS; ++i)
            *sum += cache[i];
    }
}

int main()
{
    int* vec_host = (int *) malloc(SIZE * sizeof(int));    
    for(int i = 0; i < SIZE; ++i)
        vec_host[i] = 1;

    int *vec_dev;
    int *sum_dev;
    int *cache;
    int sum_gpu = 0;

    cudaMalloc((void**) &vec_dev, SIZE * sizeof(int));
    cudaMemcpy(vec_dev, vec_host, SIZE * sizeof(int), cudaMemcpyHostToDevice);
    cudaMalloc((void**) &sum_dev, sizeof(int));
    cudaMemcpy(sum_dev, &sum_gpu, sizeof(int), cudaMemcpyHostToDevice);
    cudaMalloc((void**) &cache, BLOCKS * sizeof(int));
    cudaMemset(cache, 0, BLOCKS * sizeof(int));

    Barrier barrier;
    sum<<<BLOCKS, 1>>>(vec_dev, cache, sum_dev, barrier);

    cudaMemcpy(&sum_gpu, sum_dev, sizeof(int), cudaMemcpyDeviceToHost);

    cudaFree(vec_dev);
    cudaFree(sum_dev);
    cudaFree(cache);
    free(vec_host);
    return 0;
}

事实上,即使我将 wait() 重写为以下内容

    __device__ void wait() {
        while(*count != 234124)
            ;
    }

程序正常退出。但我希望在这种情况下会出现无限循环。


不幸的是,您想要实现的目标(块间通信/同步)在 CUDA 中并不完全可能。 CUDA 编程指南指出“线程块需要独立执行:必须能够以任何顺序、并行或串行执行它们”。此限制的原因是为了允许线程块调度程序具有灵活性,并允许代码随内核数量进行不可知的扩展。唯一支持的块间同步方法是启动另一个内核:内核启动(在同一流内)是隐式同步点。

您的代码违反了块独立性规则,因为它隐式假设内核的线程块同时执行(参见并行)。但不能保证他们会这样做。为了了解为什么这对您的代码很重要,让我们考虑一个假设的只有一个核心的 GPU。我们还假设您只想启动两个线程块。在这种情况下,你的 spinloop 内核实际上会死锁。如果线程块 0 首先在核心上调度,那么当它到达屏障时,它将永远循环,因为线程块 1 永远没有机会更新计数器。因为线程块零永远不会被换出(线程块执行到完成),所以它在旋转时会使核心之一的线程块挨饿。

有些人尝试过像您这样的方案,并取得了成功,因为调度程序碰巧以假设成立的方式安排了块。例如,曾经有一段时间,启动与 GPU 具有 SM 一样多的线程块意味着这些块是真正并发执行的。但当驱动程序或 CUDA 运行时或 GPU 的更改使该假设无效并破坏了他们的代码时,他们感到失望。

对于您的应用程序,尝试找到一个不依赖于块间同步的解决方案,因为(除非对 CUDA 编程模型进行含义更改)这是不可能的。

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

CUDA 上的块间屏障 的相关文章

  • 使用 gcc 的中间 GIMPLE 格式

    根据本文 http en wikipedia org wiki Intermediate languagegcc 在生成代码之前使用多种中间格式 我读到 GIMPLE 格式使用三个地址代码 这似乎是最容易使用的中间语言 但我需要更多细节 因
  • 浮点等于的意外结果

    问题不在于为什么0 1 0 9不等于1 0 这是关于平等者的不同行为 有人可以解释为什么下面的示例的工作方式不同 float q 0 1f float w 0 9f float summ q w q w 1 0f False summ 1
  • 为什么调用 istream::tellg() 会影响我的程序的行为?

    我正在尝试将 24 位位图图像转换为灰度图像 include
  • 通过 Office API 将多个 Word 文档保存为 HTML

    我有大量的Word文档需要解析 由于它们都是从同一个模板创建的 我认为最好的方法是将它们保存为 HTML 文件并解析 HTML 本身 虽然将单个 Word 文档保存为 HTML 相当容易 但我还没有找到从 Word 内部执行批量过程的方法
  • C中的内存使用问题

    请帮忙 操作系统 Linux 其中 sleep 1000 中 此时 top 显示Linux任务 给我写了7 7 MEM使用 valgrind 未发现内存泄漏 我明白 写得正确 所有 malloc 结果都是 NULL 但是为什么这次 睡眠 我
  • 在 C# 中将“set”添加到接口的属性中

    我希望通过为该接口中的属性提供设置访问器来 扩展 该接口 界面看起来像这样 interface IUser string UserName get 我想要这样的东西 interface IMutableUser IUser string U
  • 用于生成 C++ 代码轮廓/图的工具 - 有这样的东西吗? [复制]

    这个问题在这里已经有答案了 我需要深入研究用 C 编写的软件组件并对其进行一些修改 我幻想生成一些代码映射 它将显示类之间的关系并引导我完成方法的流程 调用图 有这个工具吗 几年前 我使用 Rational Rose 建模工具 该工具具有对
  • 将密码存储到sql中的最佳方法

    在我当前的 C Windows 应用程序中 密码已以纯文本形式存储 这显然不好 所以我只想知道加密密码并存储到 SQL Server 中的最佳方法是什么 我读到使用哈希 盐更好 但我觉得sql 2005中的 EncryptByPassPhr
  • OpenGL 着色器不与着色器程序链接

    我正在尝试使用 GLFW GLEW 添加着色器 我收到一个错误 指出着色器已加载 但它们没有有效的对象代码 这是我用于加载着色器的代码 class SHADER public void LoadShaders const char vert
  • 如何使用可变参数模板声明 std::tuple?

    也许我在这里很天真 但我相信以下代码应该编译 template
  • Microsoft ASP.NET Web Pages 2 Data Nuget 包的用途是什么?

    据我了解 ASP NET MVC 4 项目所需的最低 Nuget 包是 微软 ASP NET MVC 4 微软 ASP NET 剃刀 2 微软 ASP NET 网页 2 微软网络基础设施 不过我很想知道 以下包会添加到项目中什么 Micro
  • 如何BSWAP 64位寄存器的低32位?

    我一直在寻找如何将 BSWAP 用于 64 位寄存器的低 32 位子寄存器的答案 例如 0x0123456789abcdef位于 RAX 寄存器内 我想将其更改为0x01234567efcdab89用一条指令 因为性能 所以我尝试了以下内联
  • 从命名管道读取

    我必须实现一个 打印服务器 我有 1 个客户端文件和 1 个服务器文件 include
  • 将 dataGridView 绑定到绑定列表并按文本框过滤行

    我正在开发一个 Winforms 应用程序 并且有一个已经绑定到 dataGridView 的对象的 BindingList 我还有一个 过滤器 文本框 如果它们与文本框文本不匹配 我想从 datagridview 行中过滤掉行 我想以某种
  • 更改 RabbitMQ 队列中的参数

    我有一个 RabbitMQ 队列 最初声明如下 var result channel QueueDeclare NewQueue true false false null 我正在尝试添加死信交换 因此我将代码更改为 channel Exc
  • winapi 函数的函数指针 (stdcall/cdecl)

    请有人给我一些为 MS winapi 函数创建函数指针的提示吗 我试图为 DefWindowProc DefWindowProcA DefWindowProcW 创建一个指针 但出现此错误 LRESULT dwp HWND UINT WPA
  • Fluent NHibernate 一对一映射

    我很难利用 Fluent NHibernate 的 HasOne 映射 基本上 A 类在 B 类中可以有匹配的 只有一条或没有 记录 请帮助定义关系的 AMap 和 BMap 类 谢谢 public class A public virtu
  • 为什么(错误地)使用 ref myarray[0] 传递数组可以工作,但仅在 32 位应用程序中有效?

    我在一些互操作中做了一些愚蠢的事情 使用DllImport 在某一时刻 但它仍然可以在 32 位机器上运行 在 64 位应用程序上做了哪些不同的操作 以及为什么 导致方法 1 的行为不同 方法一 错误的方法 ref byte param S
  • 检测 Windows 重新启动是否是由于 Windows 更新造成的

    我的电脑上的一些应用程序一直在检测 Windows 更新是否重新启动 这是可以观察到的 因为它们会在 Windows 更新自动重启后重新启动 这非常有帮助 因为这些应用程序会重新加载更改 甚至unsaved更改或恢复选项卡 如果是浏览器 执
  • exit() 和 abort() 有什么区别?

    在C和C 中 有什么区别exit and abort 我试图在发生错误 不是例外 后结束我的程序 abort http en cppreference com w c program abort退出程序而不调用使用注册的函数atexit h

随机推荐

  • 禁用优化后,演示代码未能显示出 4 倍快的 SIMD 速度

    我试图了解使用 SIMD 矢量化的好处 并编写了一个简单的演示代码 以了解利用矢量化 SIMD 的算法相对于其他算法的速度增益 这是2种算法 Alg A 无矢量支持 include
  • 让 Java 通过 HTTPS 接受所有证书

    我正在尝试让 Java 接受所有通过 HTTPS 的证书 这是出于测试目的 在我收到证书未找到错误之前 但是 在我的代码之前添加以下代码后 我得到了HTTPS hostname wrong should be
  • X.509 数字签名/加密工作流程/库建议?

    我的具体用例是 我必须访问存储在客户端上的数字证书 并使用它们在客户端和服务器端执行签名 验证 加密和解密的任务 对于后一部分 解决方案有很多很多 症结在于访问客户端上存储的证书的能力 请注意 我说的是 存储在客户端上的证书 这是故意含糊其
  • 如何在每个组内创建滞后变量?

    我有一个数据表 require data table set seed 1 data lt data table time c 1 3 1 4 groups c rep c b a c 3 4 value rnorm 7 data grou
  • 如何显示 html 元素,例如通过 Html.ValidationSummary() 渲染的错误中的链接

    我的一条错误消息呈现了一个链接 然而 Html ValidationSummary 对它进行编码 因此显示如下 您指定的手机或电子邮件帐户已存在 如果您忘记了密码 请重置它 相反 它应该呈现为 您指定的手机或电子邮件帐户已存在 如果您忘记了
  • 具有多个提交按钮或多个表单的表单[重复]

    这个问题在这里已经有答案了 我有一个文章列表 我为所有文章添加了提交按钮 事实是 当我在控制器中时 我无法隐藏良好的输入 因为它将采用最后的输入
  • 为什么SqlDataReader类不能被继承?

    SqlDataReader类没有标记为 seal 那么是什么使它不可继承呢 The SqlDataReader类型的构造函数被标记为internal这意味着它只能通过类型中的实例化System Data dll集会 这也禁止您继承它 因为基
  • 如何动态更改 GLTF 模型的纹理?

    在我的场景中 我加载了一个 gltf 模型 它渲染得很好 它有一个 png 纹理 渲染在 3D 模型的表面上 是否可以通过编程方式交换纹理 我正在使用 aframe a asset item 和 a entity 来加载 gltf 资产 O
  • iPhone 崩溃并显示“无回溯”

    我的 iPhone 应用程序最近被 App Store 拒绝 因为它在启动时崩溃 但是 我无法重现此崩溃 该应用程序在模拟器和具有 Apple 测试过的相同硬件和软件的设备 运行 iOS 4 的 iPhone 3 1 上都能完美运行 他们发
  • 如何在VB.net中运行应用程序时打印行号

    我想在 VB net 应用程序中打印出带有行号的调试消息 我就是这样做的 Dim st As StackTrace Dim sf As StackFramee st New StackTrace New StackFrame True sf
  • GTK 窗口捕获:VPython (OpenGL) 应用程序

    阅读了文档后VPython and GTK 线程 在我看来 可以在 gtk GUI 中嵌入 VPython 图形 我知道这是可能的Windows 上的 wx但我在 Linux 上使用 PyGTK 现在 我已经成功地取得了部分进展 我可以嵌入
  • 在node.js 中为所有传入的http 请求提供index.html

    我有一个像这样的节点服务器 var express require express var fs require fs var path require path var root fs realpathSync var app expre
  • 无法使用 Android BluetoothProfile 连接到蓝牙 Health Device Fora

    我想通过 Android BluetoothPROfile 连接到 Fora 温度计并获取读数 以下是我的方法 在 OnCreate 中我写了这段代码 if mBluetoothAdapter getProfileProxy this mB
  • 使用 Json.net 序列化时如何根据类型更改属性名称?

    我有一个类型的属性object我必须根据它的类型更改名称 应该非常类似于 XmlElement PropertyName typeof PropertyType XML 的属性 例如 我有一个房产public object Item get
  • 延迟加载变量错误

    我正在编写一个涉及核心数据的程序 我为我创建了一个类变量context and entity并将我的代码写成这样 class PersistencyManager var context NSManagedObjectContext let
  • 无法使用 Node.js 将大块数据填充到 mongodb

    我被要求导入从全市许多站点收集的大量天气数据 每个站点有 1 台计算机 每个计算机有一个文件夹 每 5 分钟同步到一台中央服务器 每天都会创建一个新文件 所以 基本上结构是这样的 一个txt文件的格式为csv文件 其中第一行为字段 其余为数
  • PATH_TRANSLATED 中的redirect:// 是什么?

    我有一个 htaccess通过请求的规则 类别 类别 slug to 类别 php 然而 当我检查 SERVER超级全局 我得到这个条目 Array PATH TRANSLATED gt redirect 那是什么 我从未见过重定向 bef
  • allow_tags=True 不会在 django admin 中渲染
    标签

    我想在 django admin 的 list display 中显示一个表单 但我遇到了这个问题 当我定义这样的东西时 class MyModelAdmin admin ModelAdmin list display foo pagar
  • 识别并填充列表框

    这对我来说是一个谜 填充列表框的语法是什么 但首先 如何识别列表框 我在很多论坛上读到 ListBox1 Additem 但是他们怎么知道它是 ListBox1 这是默认名称ListBox当您将其添加到表单时进行控制 VB 和 VBA 自动
  • CUDA 上的块间屏障

    我想在 CUDA 上实现块间屏障 但遇到了严重的问题 我不明白为什么它不起作用 include