- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 clEnqueueWriteBuffer 有一个很好奇的问题。在我当前的项目中,我想将大约 500 张图像 (1GB) 复制到显卡上并平均一些像素。图像存储在一个大的 double* 数组中(大小:width*height*nImages)。如果我将 300 张图像复制到 VRAM 中并使用 clEnqueueReadBuffer 将其读出,我将准确获得存储在 RAM 中的内容:
内存:14450,5006076793 14450,5006076793 14456,8079379383 14455,2294939826 14444,7361060619
显存:14450,5006076793 14450,5006076793 14456,8079379383 14455,2294939826 14444,7361060619
但是,如果我加载超过 350 张图像,我的 cl_mem 对象的内容就会损坏:
内存:14450,5006076793 14450,5006076793 14456,8079379383 14455,2294939826 14444,7361060619
显存:-6,27743856220419E+66 -6,27743856220419E+66 -6,27743856220419E+66 -6,27743856220419E+66 -6,27743856220419E+66
如果你能帮助我,我会很高兴!这是我的代码:
private: System::Void button7_Click(System::Object^ sender, System::EventArgs^ e) {
std::string text;
text = StringConvA(maskedTextBox1->Text);
textBox1->Text += "You want a bin size of " + atoi(text.c_str()) + ". You have "+ nforegroundImages+" images.\r\n";
binWidth = atoi(text.c_str());
nbins = (int)ceil((double)nforegroundImages / (double)binWidth);
textBox1->Text += "That is going to give you "+nbins+" bins\r\n";
//create context and cmd_queue
context = clCreateContext(NULL, nDevices, &deviceID[0], NULL, NULL, &err);
cmd_queue = clCreateCommandQueue(context, deviceID[0], NULL, &err);
//allocate result memory
//each result image will have width*height double entries. res_im is an array of pointer to double.
res_im = (double*)malloc(width*height*sizeof(double)*nbins);
cl_mem imageData_mem, result_mem, nWavenumber_mem, binSize_mem, imageSizeInPixels_mem, nbins_mem;
imageData_mem = clCreateBuffer(context, CL_MEM_READ_ONLY, width * height * sizeof(double)*nforegroundImages, NULL, NULL);
result_mem = clCreateBuffer(context, CL_MEM_READ_WRITE, width * height * sizeof(double)*nbins, NULL, NULL);
nWavenumber_mem = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(int), NULL, NULL);
binSize_mem = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(int), NULL, NULL);
imageSizeInPixels_mem = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(int), NULL, NULL);
nbins_mem = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(int), NULL, NULL);
clFinish(cmd_queue);
int imageSizeInPixels = width*height;
err = clEnqueueWriteBuffer(cmd_queue, imageData_mem, CL_TRUE, 0, width*height*sizeof(double)*nforegroundImages, (void*)images, 0, NULL, NULL); //this is where the images are copied into VRAM. If nforegroundImages>300, the data in VRAM is wrong, otherwise it is the same as in the images array
err = clEnqueueWriteBuffer(cmd_queue, nWavenumber_mem, CL_TRUE, 0, sizeof(int), (void*)&nforegroundImages, 0, NULL, NULL);
err = clEnqueueWriteBuffer(cmd_queue, binSize_mem, CL_TRUE, 0, sizeof(int), (void*)&binWidth, 0, NULL, NULL);
err = clEnqueueWriteBuffer(cmd_queue, imageSizeInPixels_mem, CL_TRUE, 0, sizeof(int), (void*)&imageSizeInPixels, 0, NULL, NULL);
err = clEnqueueWriteBuffer(cmd_queue, nbins_mem, CL_TRUE, 0, sizeof(int), (void*)&nbins, 0, NULL, NULL);
clFinish(cmd_queue);
//read the content of imageData_mem and store it in test array
double * test = (double*)malloc(width*height*sizeof(double)*nforegroundImages);
err = clEnqueueReadBuffer(cmd_queue, imageData_mem, CL_TRUE, 0, width*height*sizeof(double)*nforegroundImages,
test, 0, NULL, NULL);
clFinish(cmd_queue);
//compare original value from the images array to the value retrieved from the VRAM
textBox1->Text += images[1] + "\t" + images[1] + "\t" + images[10] + "\t" + images[100] + "\t" + images[1000] + "\t\r\n"; //original data
textBox1->Text += test[1] + "\t" + test[1] + "\t" + test[10] + "\t" + test[100] + "\t" + test[1000] + "\t\r\n"; //retrieved from imageData_mem
free(test);
//build the program from the source file and print the program build log
cl_program program[2];
cl_kernel kernel[2];
const char * filename = "addKernel.c";
char *program_source = load_program_source(filename);
program[0] = clCreateProgramWithSource(context, 1, (const char**)&program_source,
NULL, &err);
if (err == CL_OUT_OF_HOST_MEMORY){
textBox1->Text += "Error: out of Host Memory!\r\n";
}
else if (err == CL_INVALID_CONTEXT){
textBox1->Text += "Error: invalid Context!\r\n";
}
else if (err == CL_INVALID_VALUE){
textBox1->Text += "Error: invalid Value!\r\n";
}
err = clBuildProgram(program[0], 0, NULL, NULL, NULL, NULL);
textBox1->Text += "Program build error: " + err + "\r\n";
cl_build_status status;
size_t logSize;
clGetProgramBuildInfo(program[0], deviceID[0], CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &status, NULL);
clGetProgramBuildInfo(program[0], deviceID[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize);
char* programLog;
programLog = (char*)calloc(logSize + 1, sizeof(char));
clGetProgramBuildInfo(program[0], deviceID[0], CL_PROGRAM_BUILD_LOG, logSize + 1, programLog, NULL);
this->textBox1->Text += "Program build info: error=" + err + ", status=" + status + ", programLog:\r\n" + *programLog + "\r\n" + "In case of an error please make sure that openCL has been initialized\r\n";
kernel[0] = clCreateKernel(program[0], "filterSpectrum", &err);
//(__global double *imageData, __global double *result, __constant int *nWavenumbers, __constant int *binSize, __constant int *imageSizeInPixels,__constant int * nbins)
// Now setup the arguments to our kernel
err = clSetKernelArg(kernel[0], 0, sizeof(cl_mem), &imageData_mem);
err |= clSetKernelArg(kernel[0], 1, sizeof(cl_mem), &result_mem);
err |= clSetKernelArg(kernel[0], 2, sizeof(cl_mem), &nWavenumber_mem);
err |= clSetKernelArg(kernel[0], 3, sizeof(cl_mem), &binSize_mem);
err |= clSetKernelArg(kernel[0], 4, sizeof(cl_mem), &imageSizeInPixels_mem);
err |= clSetKernelArg(kernel[0], 5, sizeof(cl_mem), &nbins_mem);
size_t local_work_size = 32;
// Run the calculation by enqueuing it and forcing the
// command queue to complete the task
size_t global_work_size = width*height;
err = clEnqueueNDRangeKernel(cmd_queue, kernel[0], 1, NULL,&global_work_size, &local_work_size, 0, NULL, NULL);
clFinish(cmd_queue);
// Once finished read back the results from the answer
// array into the results array
err = clEnqueueReadBuffer(cmd_queue, result_mem, CL_TRUE, 0, width*height*sizeof(double)*nbins,
res_im, 0, NULL, NULL);
clFinish(cmd_queue);
textBox1->Text += "result values " + res_im[1] + "\t" + res_im[100] + "\t" + res_im[1000] + "\t" + res_im[10000] + "\t" + res_im[100000] + "\t" + res_im[1000000] + "\r\n";
hScrollBar2->Maximum = nbins+3;
clReleaseMemObject(imageSizeInPixels_mem);
clReleaseMemObject(imageData_mem);
clReleaseMemObject(result_mem);
clReleaseMemObject(nWavenumber_mem);
clReleaseMemObject(binSize_mem);
clReleaseMemObject(nbins_mem);
clReleaseCommandQueue(cmd_queue);
clReleaseContext(context);
}
最佳答案
您很可能请求的内存多于驱动程序在单次分配中允许的内存。看起来您没有检查 OpenCL 运行时函数返回的大部分错误代码;这样做可以让诊断 OpenCL 程序的问题变得更容易。您确实应该为每个 API 调用执行此操作。
您可以使用以下代码片段找出您的设备支持的最大单个内存分配:
cl_ulong maxMemAlloc;
clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &maxMemAlloc, NULL);
textBox1->Text += "Maximum memory allocation size is " + maxMemAlloc + " bytes\r\n";
通常情况下,最大的内存分配远小于 GPU 内存的总大小。 OpenCL 规范仅要求它至少为最大大小的 1/4,或至少 128 MB。
关于c++ - clEnqueueWriteBuffer 将错误数据写入 VRAM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23737606/
我正在创建类似于 CUDA 的东西,但我看到将内存从 RAM 复制到 VRAM 非常快,就像从 RAM 复制到自身一样。但是从 VRAM 复制到 RAM 比从 RAM 复制到 VRAM 慢。 顺便说一
我想知道当前 nvidia/AMD 处理 VRAM 资源分配的实现。 我们已经知道,当系统 RAM 已满时,操作系统会使用交换/虚拟内存,那么对于 VRAM 来说,交换相当于什么?它们会回退到系统 R
我想使用 SDL/OpenGl/DirectX 或任何其他 API 直接从 VRAM 获取将在屏幕上显示的帧(图像)(如果可能)以二进制(RAW)格式。 我想最大限度地减少捕获屏幕的延迟,然后将其保存
假设我加载了一个或两个纹理,可能还有一些着色器、一个 VAO、一个 VBO,然后我运行该程序。 假设程序遇到某种运行时错误并在所有这些缓冲区对象和纹理被删除之前终止。 在我重新启动计算机之前,它们是否
我正在尝试获取我的游戏当前使用的 VRAM 总量。我想在我的调试信息中显示它。 当我使用 Visual Studio Graphics Analyzer 时,我想到了一个主意。我想我可以通过添加每个图
我对 clEnqueueWriteBuffer 有一个很好奇的问题。在我当前的项目中,我想将大约 500 张图像 (1GB) 复制到显卡上并平均一些像素。图像存储在一个大的 double* 数组中(大
有谁知道如何在 os x 上获得免费的(!)vram? 我知道您可以查询注册表项: typeCode = IORegistryEntrySearchCFProperty(dspPort,kIOServ
我正在分析我的简单体素化世界渲染器的性能。我想找出不同技术的性能限制,一种压力测试。在某些时候,我发现了一些非常奇怪的东西。我正在为每个 block 使用不同的 VBO 以 block 的形式分配几何
我的游戏引擎尝试分配大型纹理数组,以便能够将大部分(如果不是全部)绘制在一起。该数组可能变得足够大而无法分配,此时我会(不断)将纹理数组分成两半。 在收到 glGetError:Out of memo
我正在开发 JavaFX 程序并希望加快我的应用程序。阅读有关大图像和与之相关的问题后here ,我决定听从那里的建议并分配更多 VRAM。我不太确定如何执行此操作,但是,尽管我知道如何执行此操作,但
我正在使用 cudaMemGetInfo 来获取系统当前使用的 vram。 extern __host__ cudaError_t CUDARTAPI cudaMemGetInfo(size_t *f
我试图将比 VRAM 更多的数据传递到 GPU,这会导致以下错误。 CudaAPIError:调用 cuMemAlloc 导致 CUDA_ERROR_OUT_OF_MEMORY 我创建了此代码来重现问
我试图将比 VRAM 更多的数据传递到 GPU,这会导致以下错误。 CudaAPIError:调用 cuMemAlloc 导致 CUDA_ERROR_OUT_OF_MEMORY 我创建了此代码来重现问
我需要大致确定系统显卡有多少 VRAM。我知道我不应该这么做的所有原因,但我还是这么做了。它不需要是完美的(有些牌是谎言等),但我需要一个大概。在 Mac 上,通过核心显卡和 IOKit 可以很容易地
我目前正在编写 GameBoy Classis 模拟器。这是 GitHub 存储库 ( https://github.com/FelixWeichselgartner/GameBoy-Classic-
我想获取‖Android 设备 VRAM 大小。 有没有从程序中获取的方法? 最佳答案 让我们使用 Nexus One 进行一些计算: 屏幕分辨率为 480x800。因此所需的最小视频内存大小为: 4
TensorFlow 总是(预)分配我显卡上的所有空闲内存 (VRAM),这没关系,因为我希望我的模拟在我的工作站上尽可能快地运行。 但是,我想记录 TensorFlow 实际使用了多少内存(总计)。
我正在尝试使用 GBA 拼贴模式从头开始显示具有单一彩色像素的单个拼贴。 它主要工作,但不是设置单个像素,而是在我打算写入的 16 位对齐位置为两个字节设置相同的颜色: 通过 mgba 模拟器运行时的
我在我的应用程序中遇到了 VRAM 内存泄漏。该应用程序经常添加和删除 THREE.Geometry 以创建体积动画。如果我使用 THREE.SphereBufferGeometry 而不是具有自己填
看起来 200 万个浮点数应该没什么大不了的,只有 8MB 的 1GB GPU RAM。我有时可以分配那么多,有时甚至更多,没有任何问题。当我执行 clEnqueueReadBuffer 时,我得到
我是一名优秀的程序员,十分优秀!