Nvidia在Cg 3.1 Toolkit文档中有一些功能
arctan2实现如下
float2 atan2(float2 y, float2 x)
{
float2 t0, t1, t2, t3, t4;
t3 = abs(x);
t1 = abs(y);
t0 = max(t3, t1);
t1 = min(t3, t1);
t3 = float(1) / t0;
t3 = t1 * t3;
t4 = t3 * t3;
t0 = - float(0.013480470);
t0 = t0 * t4 + float(0.057477314);
t0 = t0 * t4 - float(0.121239071);
t0 = t0 * t4 + float(0.195635925);
t0 = t0 * t4 - float(0.332994597);
t0 …Run Code Online (Sandbox Code Playgroud) Nvidia CUDA驱动程序究竟做了什么?从使用CUDA的角度来看.驱动程序传递内核代码,执行配置(#threads,#blockss)......还有什么?
我看到一些帖子,驱动程序应该知道可用SM的数量.但这不是不必要的吗?一旦内核传递给GPU,GPU调度程序只需要将工作分散到可用的SM ......
我已经尝试了一切让OpenGL 3.2在我的游戏引擎中使用CG着色器进行渲染,但我没有运气.所以我决定做一个简单的小项目,但仍然着色器不起作用.从理论上讲,我的测试项目应该只渲染一个红色三角形,但它是白色的,因为着色器没有做任何事情.
我会在这里发布代码:
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <GL/glew.h>
#include <Cg/cg.h>
#include <Cg/cgGL.h>
#include <SDL2/SDL.h>
int main()
{
SDL_Window *mainwindow;
SDL_GLContext maincontext;
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
mainwindow = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
maincontext = SDL_GL_CreateContext(mainwindow);
glewExperimental = GL_TRUE;
glewInit();
_CGcontext* cgcontext;
cgcontext = cgCreateContext();
cgGLRegisterStates(cgcontext);
CGerror error;
CGeffect effect;
const char* string;
std::string shader;
shader =
"struct VS_INPUT"
"{"
" float3 pos : ATTR0;"
"};"
"struct FS_INPUT" …Run Code Online (Sandbox Code Playgroud) 我是CUDA初学者.
到目前为止,我了解到,每个SM都有8个块(线程).假设我有简单的工作将数组中的元素乘以2.但是,我的数据少于线程.
不是问题,因为我可以切断线程的"尾部"以使它们闲置.但是,如果我理解正确,这将意味着一些SM将获得100%的工作,而某些部分(甚至没有).
因此,我想计算哪个SM正在运行给定线程并以这种方式进行计算,每个SM具有相同的工作量.
我希望它首先有意义:-)如果是这样,如何计算给定线程运行哪个SM?或者 - 当前SM的索引和它们的总数?换句话说,在SM术语中等效于threadDim/threadIdx.
评论太久了.
罗伯特,谢谢你的回答.当我试图消化所有,这里是我做的-我有一个"大"数组,我只是有乘以值*2和它(存储阵列输出作为热身,顺便说一句我做所有的计算,数学上是正确的. ).所以首先我在1个块,1个线程中运行它.精细.接下来,我尝试以这样的方式拆分工作,即每个乘法只由一个线程完成一次.结果我的程序运行速度慢了大约6倍.我甚至感觉到为什么-小罚获取有关GPU的信息,然后计算有多少块和线程我应该使用,则每个线程,而不是单一的乘法中,现在我身边有10多只的乘法计算阵列中的偏移量一个线程.一方面,我试图找出如何改变这种不受欢迎的行为,另一方面,我想在SM中均匀地传播线程的"尾部".
我改写 - 也许我错了,但我想解决这个问题.我有1G小工作(*2就是全部) - 我应该用1K线程创建1K块,或者用1个线程创建1M块,用1M线程创建1块,依此类推.到目前为止,我读取了GPU属性,除法,除法,并盲目地使用网格/块的每个维度的最大值(如果没有要计算的数据,则使用所需的值).
size是输入和输出数组的大小.一般来说:
output_array[i] = input_array[i]*2;
Run Code Online (Sandbox Code Playgroud)
计算我需要多少块/线程.
size_t total_threads = props.maxThreadsPerMultiProcessor
* props.multiProcessorCount;
if (size<total_threads)
total_threads = size;
size_t total_blocks = 1+(total_threads-1)/props.maxThreadsPerBlock;
size_t threads_per_block = 1+(total_threads-1)/total_blocks;
Run Code Online (Sandbox Code Playgroud)
拥有props.maxGridSize和props.maxThreadsDim我以类似的方式计算块和线程的维度 - 来自total_blocks和threads_per_block.
然后是杀手部分,计算线程的偏移量(线程内部):
size_t offset = threadIdx.z;
size_t dim = blockDim.x;
offset += threadIdx.y*dim;
dim *= blockDim.y;
offset += threadIdx.z*dim;
dim *= blockDim.z; …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中的更新数据,而不是加载一些预先缓存的过时数据?
我使用CURAND生成随机数.我创建了一个curandGenerator_t填充3个大约3600万随机数的数组.每个阵列都有不同的种子.数字生成在一个循环内完成,或多或少像这样:
curandGenerator_t randGenerator;
curandCreateGenerator(&randGenerator, CURAND_RNG_PSEUDO_DEFAULT);
for(i = 0; i < 100; i++)
{
curandSetStream(randGenerator, stream[0]);
curandSetPseudoRandomGeneratorSeed(randGenerator, seed[0]);
curandGenerateUniformDouble(randGenerator, d_rv0, N);
curandSetStream(randGenerator, stream[1]);
curandSetPseudoRandomGeneratorSeed(randGenerator, seed[1]);
curandGenerateUniformDouble(randGenerator, d_rv1, N);
curandSetStream(randGenerator, stream[2]);
curandSetPseudoRandomGeneratorSeed(randGenerator, seed[2]);
curandGenerateUniformDouble(randGenerator, d_rv2, N);
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,因为我得到的结果是那些预期的但是在分析应用程序后我意识到在循环的一些迭代之后随机数的生成变得更慢.在下图中,蓝绿色项目从100毫秒到1秒.
有人可以解释这是否是随机数生成的正常行为?
我做错了用三个不同的种子和一个curandGenerator生成随机数吗?

我想知道如何让OpenCl"看到"我的K20.Xeon和Xeon Phi在同一时间?
特别是我对这里使用两个库感到困惑(来自NVidia和Intel).
怎么做,如果可能的话?
我正在Cuda开发一些简单的程序,我想知道哪个线程正在执行GPU的哪个核心.我正在使用Visual Studio 2012,我有一块NVIDIA GeForce 610M显卡.
是否有可能这样做...我已经在谷歌搜索了很多但都是徒劳的.
编辑:
我知道这真的很奇怪,但我的大学项目指南要求我这样做.
Nvidia GPU列表 - GeForce 900系列 - 有写道:
4单精度性能计算为着色器数量乘以基本核心时钟速度的2倍.
例如,对于GeForce GTX 970,我们可以计算性能:
1664核心*1050 MHz*2 = 3 494 GFlops峰值(3 494 400 MFlops)
我们可以在列中看到这个值 - 处理能力(峰值)GFLOPS - 单精度.
但为什么我们必须乘以2?
写道:http://devblogs.nvidia.com/parallelforall/maxwell-most-advanced-cuda-gpu-ever-made/
SMM使用基于象限的设计,具有四个32核处理模块,每个模块具有专用的warp调度程序,能够在每个时钟发送两条指令.
好的,nVidia Maxwell是超标量体系结构,每个时钟发送两条指令,但是1个CUDA内核(FP32-ALU)每个时钟可以处理多于1条指令吗?
我们知道1个CUDA-Core包含两个单元:FP32-unit和INT-unit.但INT-unit与GFlops(每秒浮点运算)无关.
即一个SMM包含:
要获得GFlops的性能,我们应该只使用:128个FP32单元和32个SFU单元.
即如果我们同时使用128个FP32单元和32个SFU单元,那么我们可以获得160个指令,每个SM每个时钟具有浮点运算.
也就是说,我们必须通过1,2 =(160/132)的instad为2.
1664核心*1050 MHz*1,2 = 2 096 GFlops峰值
为什么在wiki中写入我们必须多个核心*MHz乘2?