我基本上自学了C/C++编程,所以我对编程习惯不太了解.总有一件事让我想知道为什么人们总是喜欢在他们的代码中添加操作符之间的间距,例如:
if(x > 0)
Run Code Online (Sandbox Code Playgroud)
代替
if(x>0)
Run Code Online (Sandbox Code Playgroud)
这有什么特别的原因吗?我们知道编译器只是忽略了这种间距,我不认为后一种表达式的可读性较差.
假设进程中有足够的虚拟内存地址.
考虑到64位系统具有几乎无限的虚拟地址,并且如果OS内存池中仍有可用的物理内存空间,我们可以假设内存分配失败的可能性为零吗?
考虑以下场景:
函数A创建一层OMP并行区域,每个OMP线程调用一个函数B,函数B本身又包含一层OMP并行区域。
然后,如果在函数 B 的并行区域内,有一个 OMP 关键区域,那么,该区域对于函数 A 和 B 创建的所有线程是“全局”关键的,还是仅对函数 B 是局部的?
如果 B 是预先构建的函数(例如静态或动态链接库)怎么办?
关于性能,假设我们获得了每个线程可以频繁访问的数据块,并且这些数据是只读的,这意味着线程除了读取数据之外不会做任何事情.
那么为每个线程创建这些数据的一个副本(假设数据是只读的)是否有益?
如果所有线程共享频繁访问的数据(而不是每个线程一个副本),这是否会增加这些数据被正确缓存的可能性?
我的理解是,warp 是通过任务调度程序在运行时定义的一组线程,CUDA 的一个性能关键部分是 warp 内线程的分歧,有没有办法很好地猜测硬件将如何构造 warp在线程块内?
例如,我启动了一个线程块中包含 1024 个线程的内核,扭曲是如何排列的,我可以从线程索引中看出(或至少做出一个很好的猜测)吗?
因为通过这样做,可以最大限度地减少给定经纱内线程的发散。
从绩效角度来看,还有更好的方法吗?
例如,创建一个名为arraydata的类/结构,它分配一些对齐的内存供使用(尽管由.dataPtr提供的指针):
class arraydata//to allocate some memory,
//and return a pointer to that block of memory
{
void *dataPtrV;
public:
double *dataPtr;
arraydata(int a, int b)
{
dataPtrV=_aligned_malloc(a*b*sizeof(double),32);
dataPtr=(double *)dataPtrV;
}
~arraydata()
{
_aligned_free(dataPtrV);
dataPtrV=NULL;
dataPtr=NULL;
}
};
Run Code Online (Sandbox Code Playgroud)
然后叫它:
arraydata X(30,20);
Run Code Online (Sandbox Code Playgroud) nvcc如何处理内核中的const指针?
根据nvidia的说法,在参数传递过程中为指针添加const和restrict会使NVCC进行积极优化,这是否严格遵循C/C++方式?
假设A指针指向数据缓冲区,该缓冲区可能被其他线程/流频繁地更新,但在此测试内核调用期间内容不会被修改:
test<<<blocks, threads>>>(const int *__restrict__ A, int *__restrict__ B);
Run Code Online (Sandbox Code Playgroud)
然后NVCC可以保持这种正确性:在每次内核调用时加载A中的更新数据,而不是加载一些预先缓存的过时数据?
在主机代码中,__CUDA_ARCH__宏似乎不会生成不同的代码路径,相反,它将生成代码以确保当前设备的代码路径.
但是,如果__CUDA_ARCH__在设备代码中,它将为编译选项(/ arch)中指定的不同设备生成不同的代码路径.
谁能证实这是正确的?
在共享内存编程模型中,每个线程都可以看到任何全局变量.
在CUDA中,常量内存以类似于共享内存系统中的全局变量的方式声明,这让我有点担心:
考虑以下代码:
__constant__ int array[1024];
void hostFunction(int DeviceID, cudaStream_t streamIdx)
{
cudaSetDevice(DeviceID);
someKernel<<<100,1024,0, streamIdx>>>(...);
//The function someKernel will use data stored in array[] on current device;
};
Run Code Online (Sandbox Code Playgroud)
然后,是array[]每个cuda上下文/设备的本地内容,这样我们可以安全地更新每个设备的"私有" array[]而不用担心改变array[]其他cuda设备上分配的值吗?
顺便说一句:我搜索了网站,有一些相关的问题,但我找不到任何这些明确的答案.
考虑以下主机功能:
uint64_t * SomeDevPtr =...
/* Where SomeDevPtr is a pointer pointed to some device memory address allocated by cudaMalloc(); */
uint32_t * SomeDevIntPtr = reintepret_cast<uint32_t *>(SomeDevPtr);
Run Code Online (Sandbox Code Playgroud)
由于该功能,cudaMalloc将automatcially fullfill一些aligment要求(我认为它对准一些128字节存储器边界),因此,我认为无论是SomeDevIntPtr和SomeDevPtr应在GPU的全局内存确切相同的物理内存地址开始,我是正确的这一?
我只是想确定一下,因为我编写的一些函数依赖于它.
datatype *x;//where datatype is a class defined earlier;
//...
if (isDataType(x[0]))//test whether x[0] belong to datatype defined.
//do something
Run Code Online (Sandbox Code Playgroud)
是否有任何C++功能可以像上面那样做?