我读了一些引用本地内存的CUDA文档.(这主要是早期文档.)设备属性报告本地mem大小(每个线程)."本地"记忆是什么意思?什么是'本地'记忆?"本地"记忆在哪里?如何访问"本地"内存?这是__device__记忆,不是吗?
设备属性还报告:全局,共享和常量mem大小.这些陈述是否正确:
全局记忆是__device__记忆.它具有网格范围和网格(内核)的生命周期.
常量内存是__device__ __constant__内存.它具有网格范围和网格(内核)的生命周期.
共享内存是__device__ __shared__内存.它具有单个块范围和该块(线程)的生命周期.
我在想共享内存是SM内存.即只有那个SM才能直接访问的内存.资源相当有限.SM是不是一次分配了一堆块?这是否意味着SM可以交错执行不同的块(或不是)?即运行阻止*A*线程直到它们停止.然后运行block*B*线程直到它们停止.然后再次换回阻止*A*线程.或者SM是否为块*A*运行一组线程,直到它们停止.然后交换另一组块*A*线程.此交换继续,直到块*A*用尽.然后,只有这样才能在块*B*上开始工作.因为共享记忆,我问.如果单个SM从2个不同的块交换代码,那么SM如何快速交换/分出共享内存块?(我认为后来的senerio是真的,并且没有交换共享内存空间.块*A*运行直到完成,然后块*B*开始执行.注意:块*A*可能是不同的内核比块*B*.)
我的代码给出了一条错误消息,我试图找出它的原因.为了更容易找到问题,我删除了显然与导致错误消息无关的代码.如果您能告诉我为什么以下简单代码会产生错误消息,那么我认为我应该能够修复原始代码:
#include "cuComplex.h"
#include <cutil.h>
__device__ void compute_energy(void *data, int isample, int nsamples) {
cuDoubleComplex * const nminusarray = (cuDoubleComplex*)data;
cuDoubleComplex * const f = (cuDoubleComplex*)(nminusarray+101);
double * const abs_est_errorrow_all = (double*)(f+3);
double * const rel_est_errorrow_all = (double*)(abs_est_errorrow_all+nsamples*51);
int * const iid_all = (int*)(rel_est_errorrow_all+nsamples*51);
int * const iiu_all = (int*)(iid_all+nsamples*21);
int * const piv_all = (int*)(iiu_all+nsamples*21);
cuDoubleComplex * const energyrow_all = (cuDoubleComplex*)(piv_all+nsamples*12);
cuDoubleComplex * const refinedenergyrow_all = (cuDoubleComplex*)(energyrow_all+nsamples*51);
cuDoubleComplex * const btplus_all = (cuDoubleComplex*)(refinedenergyrow_all+nsamples*51);
cuDoubleComplex * const btplus = btplus_all+isample*21021; …Run Code Online (Sandbox Code Playgroud) 我想要一些固定数量的变量的代码块,比如说:
MyGenericClass<T> v1,v2,v3;
/* ... */
{
/* something with v1 */
}
{
/* same thing with v2 */
}
{
/* same thing with v3 */
}
Run Code Online (Sandbox Code Playgroud)
我想避免代码重复.这样做的最佳方法是什么(希望不会为GC创建对象,因为这些代码会运行很多)?
这有效:
for (MyGenericClass<S> v : new MyGenericClass[] {v1,v2,v3}) {
/* something with v - no casting */
}
Run Code Online (Sandbox Code Playgroud)
带有类型安全警告,如下所示:
for (MyGenericClass<S> v : Arrays.asList(v1,v2,v3) {
/* something with v - no casting */
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢哪一个?还有更好的选择吗?
我有一个表 T1,我想要一个具有两倍行数的新表:一个额外的列,该列获取 0(对于 T1 的一个副本)和 1(对于 T1 的第二个副本)。
换句话说,我想将 T1 与具有一个布尔列和所有可能值的常量表交叉连接。
在 MySQL 中执行此操作的最佳/最有效/更合适的方法是什么?
我的编译器支持C++ 03.我应该使用哪个版本的提升?如果我使用的是早期版本的C++,我将如何建立升级版本?
我有一个函数myFunction的Function<Integer, T>,我想构造一个对象mylist的大小size,实现List<T>(或者某种不可变列表界面),通过功能的支持,在这个意义上mylist.get(i) == myFunction.apply(i).
我可以手动执行此操作,但是有一些(Guava)代码也可以这样做吗?
我的理解是,warp 是通过任务调度程序在运行时定义的一组线程,CUDA 的一个性能关键部分是 warp 内线程的分歧,有没有办法很好地猜测硬件将如何构造 warp在线程块内?
例如,我启动了一个线程块中包含 1024 个线程的内核,扭曲是如何排列的,我可以从线程索引中看出(或至少做出一个很好的猜测)吗?
因为通过这样做,可以最大限度地减少给定经纱内线程的发散。
我试图写一个循环,遍历几行文本,将每一行 - 每个字符串 - 分成两个元素,结果填充一个二维数组.我目前在java.lang.ArrayIndexOutOfBoundsException: 0下面的代码中遇到错误,在线上触发split().我想获取split()调用的结果并将其与我的程序的其余部分一起使用.另外,如果我没有在第二个数组框中放置一个整数,我会得到一个编译错误 - 预计会出现一个参数.
String[][] arr = new String[numLines.size()][];
for(int i = 0 ; i < numLines.size(); i++) {
arr[i][1].split("--", 2);
/* ... */
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试编译一个包含 MSVS 2012 和 CUDA 内核的程序。我使用共享内存,但与此问题中关于同一问题的问题不同,我只对该内核的共享内存使用我的变量名称一次,因此不存在重新定义的问题。使用这样的代码:
template<typename T>
__global__ void mykernel(
const T* __restrict__ data,
T* __restrict__ results)
{
extern __shared__ T warp_partial_results[];
/* ... */
warp_partial_results[lane_id] = something;
/* ... */
results[something_else] = warp_partial_results[something_else];
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
它被实例化为多种类型(例如 float、int、unsigned int),我得到了可怕的
Run Code Online (Sandbox Code Playgroud)declaration is incompatible with previous "warp_partial_results"
信息。什么可能导致这种情况?
假设我有一堆带有一堆块的CUDA内核,并假设在同一个对称多处理器上的另一个块之后安排了一个块(也就是说,所有warp的共享内存区域相同的单元).目前,NVIDIA没有在API或每GPU文档中指定执行之间共享内存会发生什么.但实际上,关于块的共享内存内容,下列哪一项呢?:
为了缩小可能出现的情况的变化,请具体参考每个块使用最大可能共享内存量的情况 - 在Kepler GPU上为48 KB.