问题标签 [c++-amp]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
242 浏览

random - 链接错误,包括 C++ AMP 中的随机数库

我正在使用Codeplex的C++ AMP tinymt 库来生成随机数。该库工作正常,除了当我在同一个项目中的两个不同文件中时,出现链接错误,提到重新定义某些变量tinymt_lib::tinymt_dc_datatinymt_dc_data_32#include <amp_tinymt_rng.h>

#pragma once考虑到我已经在每个标题中使用,什么是摆脱这个问题的好方法?我正在使用 Visual Studio 2013 Professional。

作为一个附带建议,在没有特殊库开销的情况下生成随机数的更简单方法是什么?我不担心序列不是安全随机的、简单的random()rand()足够的。

0 投票
1 回答
730 浏览

c++ - 为什么我不能在 Visual Studio 2013 下使用 FFTW 或 AMPFFT 获得有效的二维 FFT?

我一直在我的一个项目中使用 2D FFT,并且无法使用两个不同的 FFT 库获得正确的结果。起初我以为我用错了,但在与 MATLAB 和 Linux GCC 参考实现进行比较后,现在我的编译器(MSVC 2013 express)似乎发生了一些险恶的事情。

我的测试用例如下:256x256 复杂到真正的 IFFT,单个 bin 为 255(X,Y 表示法为 0,255)设置为 10000。

使用 AMFFFT,我得到以下 2D 变换:

损坏的 AMFFFT 示例

使用 FFTW,我得到以下 2D 变换:

损坏的 FFTW 示例

如您所见,AMPFFT 版本有点“几乎”正确,但有一点很奇怪,每个样本都有条带,而 FFTW 版本到处都是,出去吃午饭了。

我获取了两个不同测试版本的输出并将它们与 MATLAB(技术上是 octave,它在引擎盖下使用 FFTW)进行了比较。我还在 Linux 下使用 GCC 为 FFTW 运行了相同的测试用例。这是第 127 行的一组测试中的一个片段(行号在技术上并不重要,因为我选择的 bin 所有行都应该是相同的):

FFT 比较

在这个例子中,octave 和 Linux 实现代表正确的结果并遵循红线(octave 绘制为黑色,Linux 绘制为红色,它与 octave 完全一致)。MSVC 下的 FFTW 绘制为蓝色,AMP FFT 输出绘制为洋红色。正如你所看到的,AMPFFT 版本似乎几乎接近了,但其中有这种奇怪的高频纹波,而 MSVC 下的 FFTW 只是一团糟,有这种奇怪的“打包”外观。

在这个阶段,我只能将矛头指向 Visual Studio,但我不知道发生了什么或如何修复它。

这是我的两个测试程序:

FFTW 测试:

AMPFFT 测试:

这两个都是在 MSVC 2013 上为 win32 控制台应用程序使用股票设置编译的,FFTW 测试也在 Centos 6.4 和 GCC 4.4.7 下运行。两个 FFTW 测试都使用 FFTW 版本 3.3.4,并且同时测试了复杂到真实和复杂到复杂的计划(结果相同)。

有没有人对我可以尝试解决这个问题的 Visual Studio 编译器设置有丝毫线索?

0 投票
3 回答
743 浏览

c++ - C++ 放大器原子

我正在用 C++ AMP 重写一个算法,但遇到了原子写入的问题,更具体地说 atomic_fetch_add,这显然只适用于整数?

我需要以原子方式添加一个 double_4(或者如果我必须添加一个 float_4)。如何使用 C++ AMP 的原子实现这一点?

最好/唯一的解决方案真的有一个我的代码可以用来控制写入的锁变量吗?我实际上需要为一长串输出双打执行原子写入,所以我基本上需要为每个输出设置一个锁。

我已经考虑过平铺这个以获得更好的性能,但现在我只是在第一次迭代中。

编辑:感谢您已经给出的快速答案。不过,我对我的问题有一个快速更新。

我进行了以下锁定尝试,但似乎当经线中的一个线程越过锁时,同一经线中的所有其他线程都只是跟随。我期待第一个经线得到锁,但我一定错过了一些东西(请注意,自从我的 cuda 时代以来已经有好几年了,所以我刚刚变得愚蠢)

这不是一个大问题,因为我应该首先写入一个共享变量,并且只有在一个 tile 中的所有线程都完成后才将它写入全局内存,但我就是不理解这种行为。

0 投票
1 回答
325 浏览

gpgpu - C++ AMP (GPU) 全局写入更新速度不够快,以至于所有图块都能看到?

我认为这是一个 GPU 问题而不是 C++ AP 问题,因此我对其进行了广泛的标记。

我有一个计算的实现,它将工作分成许多块来完成它们的工作,然后将结果添加到全局内存中的现有值中。首先,tile 中的每个线程都将它们的部分结果计算到 tile_static 内存中,每个线程都有一个要写入的索引。稍后,图块中的第一个线程会将所有部分结果汇总在一起,并将总和添加到全局内存中的某个位置。

瓦片(瓦片中的线程 0)有时会想要写入相同的位置,所以我添加了简单的锁定。

我传递给 lock 和 unlock 的 lock 变量位于一个全局整数数组中,每个争用内存位置一个整数,tile 将写入。

瓦片结果的实际写入,由瓦片中的第一个线程完成,是这样完成的

这大部分都可以,但并非总是如此。必须存在一些竞态条件,因为当相对于要写入的内存位置数量而言,tile 太多时(过多的锁争夺),有时它会无法正确添加 tile 结果。

似乎有时,虽然很少,锁定/解锁设置不能确保正确添加。

这可以通过将锁向上移动到求和前面来“修复”,因此从获得锁到 thread0 进行实际写入之前需要更长的时间。当我在总和中剩下五个元素时,我也可以通过锁定来“修复”它。两者都如下图

第一次修复,速度很慢(阻塞太久)

第二次修复,速度更快

看看这些“修复”是如何工作的,很明显,一些内存写入在系统范围内的更新速度不够快。一个磁贴可以锁定一个位置,写入它并解锁。然后另一个图块获得锁,进行添加(但指的是旧的未更新数据)并解锁。

锁是一个 int,数据是一个 double_4,所以看起来锁的释放和更新速度足够快,以便其他图块在数据仍在传输中时看到。即使第一个写入的块还没有完全提交,另一个块可以看到锁是空闲的。因此,第二个图块从缓存中读取未更新的数据值并添加到它并写入...

有人可以帮我理解为什么当第一个磁贴写入时数据没有失效(在缓存中),有人可以帮我找到解决这个问题的正确方法吗?

0 投票
0 回答
121 浏览

debugging - 为 c# windows store 应用程序选择 GPU 调试类型

我有一个带有 C# XAML windows store 应用程序和一个公开 C++ AMP 代码的 WinRT 组件的解决方案。设置了从应用程序到组件的引用,我可以运行它,并且通过混合模式调试,我可以进入 win rt 组件。

但是,我不能选择“仅 gpu”的“调试器类型”,它使用软件仿真 gpu 调试器启动调试。我可以选择混合模式并调试 c# app 和 c++ rt 组件,但是 gpu 不可用,所以我无法进入内核的实际 parallel_for_each 代码块。

如果我使用 C++ XAML windows store 应用程序作为主机,我可以很容易地选择“gpu only”作为调试器类型。

一种解决方案是在不调试的情况下构建并启动解决方案(C# app+C++ 组件),然后手动进入 debug/attach 处理并找到我正在运行的进程,选择 gpu debugger 并附加。这实际上有效,只要我手动确保使用正确的加速器。

由于我可以通过手动附加以迂回的方式进行调试,因此很明显它应该能够通过正常的 F5 运行和调试来工作,这基本上以更简单的方式完成了同样的事情。

我很想知道如何将它设置为像往常一样工作,以及我遇到困难的原因是什么。

NB。我有一篇关于这个的帖子,其中有不同的措辞和标签,因为当时我并没有真正理解问题和解决方法。我删除了那个帖子并写了这个。

0 投票
1 回答
908 浏览

c++ - 为什么在这种情况下 PPL 比顺序循环和 OpenMP 慢得多

关于我对 CodeReview 的问题,我想知道为什么 PPL 实现两个向量的简单变换比顺序和使用 OpenMP 的 for 循环std::plus<int>慢得多(顺序(带矢量化):25ms,顺序(不带矢量化) std::transform:28ms,C++AMP:131ms,PPL:51ms,OpenMP:24ms)。

我使用以下代码进行分析,并在 Visual Studio 2013 中进行了全面优化:

0 投票
3 回答
1134 浏览

c++ - 在 C++AMP 的 parallel_for_each 中使用用户指定的函数

我目前正在编写一个库,我希望能够允许用户定义一个函数(声明为restrict( amp ))并允许他们将此函数传递给我的一个库函数以在concurrency::parallel_for_each循环中使用。例如:

我希望这能够工作,只要f将其声明为有效的 AMP 兼容函数,就好像我f直接用内核中的函数本身替换函数指针一样;一切都按预期工作。但是,使用f会导致以下错误:

不支持函数指针、函数引用或指向成员函数的指针。

有什么方法可以在不阻止我的用户使用 lambdas 以外的函子的情况下获得我想要的行为?

0 投票
1 回答
876 浏览

c++ - 由 C++AMP 方法产生的 DXGI_ERROR_DEVICE_HUNG

我正在尝试实现一个函数,该函数使用 C++AMP 计算 Gauss-Laguerre 数值积分方法的权重和横坐标以并行化该过程,并且在运行它时出现DXGI_ERROR_DEVICE_HUNG错误。

这是我在 GPU 上计算 gamma 函数对数的辅助方法:

这是我计算权重和横坐标的函数:

这是来自调试控制台的完整跟踪:

D3D11:移除设备。D3D11 错误:ID3D11Device::RemoveDevice:设备删除已被触发,原因如下(DXGI_ERROR_DEVICE_HUNG:设备执行其命令的时间不合理,或硬件崩溃/挂起。因此,TDR(超时检测和恢复)机制已被触发。当前的设备上下文在挂起时正在执行命令。应用程序可能希望重新生成并回退到不太积极地使用显示硬件)。[执行错误 #378:DEVICE_REMOVAL_PROCESS_AT_FAULT] D3D11 错误:ID3D11DeviceContext::Map:返回 DXGI_ERROR_DEVICE_REMOVED,当资源尝试使用 READ 或 READWRITE 进行映射时。[ RESOURCE_MANIPULATION 错误 #2097214:RESOURCE_MAP_DEVICEREMOVED_RETURN]

我很抱歉无法制作一个可重复的小例子;我希望这仍然是一个可以接受的问题,因为我自己无法解决这个问题。

0 投票
2 回答
206 浏览

c++ - 使用受限函数时出现尾随返回类型问题

我正在使用 C++AMP 为内部编写一个库,我发现以下内容不起作用,我很好奇为什么(如果我restrict(amp)从仿函数中删除它会起作用):

但是,如果我restrict(amp)从 的定义中删除f,程序将按预期编译。AMP 开放标准中是否有可以阐明这一点的条款?


此外,如果我们在 的定义中使用以下内容,TestFunc即使使用说明符,它也可以正确编译restrict(amp)

0 投票
1 回答
830 浏览

c++ - C++ amp:异步传输数据并将数据保存在加速器上

我有一个经常被调用的函数,它非常适合并行处理,所以我研究了 C++ amp 作为初学者。该函数接受三个输入:

  1. 一个浮点向量,它是输入数据
  2. 常数系数的向量,在整个调用过程中保持不变
  3. 输出向量,将结果写入其中。

现在很明显,每次调用都必须将#1 复制到 GPU 上。为此,我使用了一个堆栈管理的 const array<>,它工作得很好。

对于#2,最佳情况是以某种方式将向量保留在 GPU 内存中,因为它是恒定的。这可以使用amp吗?还是每次调用parallel_for_each时都必须复制它,类似于#1?

对于#3,是否可以在 GPU 上分配缓冲区并将其复制回来,而不是在 cpu 堆栈上创建一个空缓冲区,复制它,并在结果写入后将其复制回来?

最后一件事,由于 parallel_for_each 调用本质上是异步的 - 并且将由 #3 的析构函数或 array_view::synchronize() 同步,是否可以离开当前函数(和堆栈空间),同时做一些其他的事情GPU正在处理,然后在稍后“同步”?

它需要一个动态分配的array_view来避免销毁时的同步(),但是当我使用指针而不是堆栈管理的对象时,该函数似乎不会编译:

另外,对于那些在 OpenCL 等其他架构方面经验丰富的人,我会在那里有更好的运气吗?