标签: gpu

GPU 如何将线程分组为扭曲/波前?

我的理解是,warp 是通过任务调度程序在运行时定义的一组线程,CUDA 的一个性能关键部分是 warp 内线程的分歧,有没有办法很好地猜测硬件将如何构造 warp在线程块内?

例如,我启动了一个线程块中包含 1024 个线程的内核,扭曲是如何排列的,我可以从线程索引中看出(或至少做出一个很好的猜测)吗?

因为通过这样做,可以最大限度地减少给定经纱内线程的发散。

gpu gpgpu gpu-warp

2
推荐指数
1
解决办法
2197
查看次数

启动内核时共享内存和流

我是 CUDA 新手,正在从事个人项目。我知道,如果您想在启动时指定共享内存量:

kernel<<<grid_size,block_size,shared_mem_size>>>(parameters);
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我想将内核放入流中:

kernel<<<grid_size,block_size,0,stream_being_used>>>(parameters);
Run Code Online (Sandbox Code Playgroud)

我不明白为什么第三个参数在流的情况下是0?(我是从 Sanders 和 Kandrot 的《CUDA 示例》第 10 章中得到的)。

如果我想在启动时指定共享内存并将其放入流中,我该如何正确执行此操作?换句话说,中间的参数应该<<<...>>>是什么样的?

c cuda gpu gpu-shared-memory

2
推荐指数
1
解决办法
2678
查看次数

C CUDA 内核的 PtrStepSz(GpuMat) 数组

我正在尝试使用 CUDA 内核内的 GpuMats 数组的信息修改 GpuMat。
为了修改它,我发送 GpuMat 并将其转换为内核中的 PtrStepSz,如下所示:

__global__ void func(cuda::PtrStepSz<float> X)
{//...
}
int main()
{//...
    GpuMat X;
    func<<<blocks, threads>>>(X);
}
Run Code Online (Sandbox Code Playgroud)

工作正常...现在我正在尝试使用 PtrStepSz 数组的信息...我一直在尝试类似的方法:

__global__ void func2(cuda::PtrStepSz<float> arr[])
{//...
}
int main()
{
    cuda::PtrStepSz<float> *d_arr;
    cudaMalloc((void**)&d_arr, sizeof(cuda::PtrStepSz<float>)*N );
    cuda::GpuMat mats[N];
    Mat O = Mat::ones(size, size, CV_32FC1);
    for (int i = 0; i < N; i++){
      mats[i].upload(O);
      d_arr[i] = mats[i];
    }
    func2<<<blocks, threads>>>(d_arr);
    //...
}
Run Code Online (Sandbox Code Playgroud)

这不起作用...甚至初始化部分也不行(我想这是因为我无法从CPU修改GPU内容)...关于如何完成我需要的任何想法?谢谢你的帮助

c++ opencv cuda gpu

2
推荐指数
1
解决办法
2391
查看次数

对 GPU 上的数组执行推力::min_element

我试图找到 GPU 上数组的最小值。我可以在 cpu 上使用 min_element,但不知道如何在 gpu 上使用 min_element。我也很困惑为什么 min_element 的返回必须是一个数组,因为只有一个最小值?这是最接近我认为正确的,但我得到:'错误:对于 min_element 行,不存在从“thrust::device_ptr”到“double *”的合适转换函数。

代码:

#include <stdio.h>
#include <stdlib.h> /* for rand() */
#include <unistd.h> /* for getpid() */
#include <time.h> /* for time() */
#include <math.h>
#include <assert.h>
#include <iostream>
#include <ctime>
#include <thrust/scan.h>
#include <thrust/device_ptr.h>
#include <thrust/reduce.h>
#include <thrust/extrema.h>
#include <cuda.h>

using namespace std;

bool errorAsk(const char *s="n/a")
{
cudaError_t err=cudaGetLastError();
if(err==cudaSuccess)
    return false;
printf("CUDA error [%s]: %s\n",s,cudaGetErrorString(err));
return true;
};

double *fillArray(double *c_idata,int N,double constant) {
    int …
Run Code Online (Sandbox Code Playgroud)

cuda gpu thrust

2
推荐指数
1
解决办法
1405
查看次数

在 CUDA 内核 __global___ 内调用推力函数

我读到过有关 CUDA 的新版本支持动态并行性的信息,并且我可以像thrush::exclusive_scan在带有参数的内核函数内部一样调用推力函数thrust::device

__global__ void kernel(int* inarray, int n, int *result) {
  extern __shared__ int s[];
  int t = threadIdx.x;

  s[t] = inarray[t];
  __syncthreads();

  thrust::exclusive_scan(thrust::device, s, n, result);
  __syncthreads();
}

int main() {
  // prep work

  kernel<<<1, n, n * sizeof(int)>>>(inarray, n, result);
}
Run Code Online (Sandbox Code Playgroud)

我感到困惑的是:

  1. 当在内核内部调用推力函数时,每个线程是否调用该函数一次,并且它们都对数据进行动态并行处理?
  2. 如果他们这样做了,我只需要一个线程来调用thrust,这样我就可以做一个ifto threadIdx;如果没有,块中的线程如何相互通信,以确保对推力的调用已完成,并且它们应该忽略它(这似乎有点想象,因为没有系统的方法来确保用户的代码)。总结一下,当我thrust::device在内核中调用带参数的推力函数时到底发生了什么?

c++ cuda gpu thrust

2
推荐指数
1
解决办法
1437
查看次数

使用 Nvidia NPP 调整图像大小时出现未记录的调整大小错误

我正在尝试使用 Nvidia 性能基元库来调整图像大小,但该nppiResize_8u_C3R函数抛出NPP_RESIZE_FACTOR_ERROR的错误未在文档中列出作为该函数的错误返回代码之一。这是我希望简单的代码:

#include <iostream>
#include <nppi.h>

int image_a_pitch;
NppiSize image_a_size = {.width = 960, .height = 540};
NppiRect image_a_roi = {.x = 0, .y = 0, .width = 960, .height = 540};
Npp8u* image_a = nppiMalloc_8u_C3(960, 540, &image_a_pitch);

int image_b_pitch;
NppiSize image_b_size = {.width = 960, .height = 540};
NppiRect image_b_roi = {.x = 0, .y = 0, .width = 960, .height = 540};
Npp8u* image_b = nppiMalloc_8u_C3(960, 540, &image_b_pitch);

NppStatus result = nppiResize_8u_C3R(image_a, image_a_pitch, …
Run Code Online (Sandbox Code Playgroud)

c++ cuda gpu image-processing npp

2
推荐指数
1
解决办法
1990
查看次数

OpenCV - 将 GpuMat 复制到 cuda 设备数据中

我正在尝试将 a 中的数据复制cv::cuda::GpuMatuint8_t*要在内核中使用的变量。

GpuMat 包含分辨率为 752x480 且类型为 CV_8UC1 的图像数据。下面是示例代码:

uint8_t *imgPtr;
cv::Mat left, downloadedLeft;
cv::cuda::GpuMat gpuLeft;

left = imread("leftview.jpg", cv::IMREAD_GRAYSCALE);
gpuLeft.upload(left);

cudaMalloc((void **)&imgPtr, sizeof(uint8_t)*gpuLeft.rows*gpuLeft.cols);
cudaMemcpyAsync(imgPtr, gpuLeft.ptr<uint8_t>(), sizeof(uint8_t)*gpuLeft.rows*gpuLeft.cols, cudaMemcpyDeviceToDevice);

// following code is just for testing and visualization...
cv::cuda::GpuMat gpuImg(left.rows, left.cols, left.type(), imgPtr);
gpuImg.download(downloadedLeft);
imshow ("test", downloadedLeft);
waitKey(0);
Run Code Online (Sandbox Code Playgroud)

但输出并不如预期。以下分别是输入和输出图像。

输入 输入图像

输出 在此输入图像描述

我已经尝试将cv::Mat源提供给cudaMemcpy. 看起来运行良好。问题似乎与cv::cuda::GpuMat和有关cudaMemcpy这里讨论了类似的问题

另外,如果图像是 256 或 512,则程序似乎运行良好。

我缺少什么?应该怎样做才能使 752x480 图像正常工作?

c++ opencv cuda gpu nvidia

2
推荐指数
1
解决办法
8701
查看次数

CUDA 中的块间同步

我为这个问题搜索了一个月。我无法同步 CUDA 中的块。

我读过很多关于atomicAdd、合作组等的文章。我决定使用一个全局数组,这样一个块就可以在全局数组的一个元素上写入。写入之后,块的线程将等待(即陷入 while 循环),直到所有块都写入全局数组。

当我使用 3 个块时,我的同步效果很好(因为我有 3 个 SM)。但使用 3 个街区可以让我获得 12% 的入住率。所以我需要使用更多的块,但它们无法同步。问题是:SM 上的一个块等待其他块,因此 SM 无法获取另一个块。

我能做些什么?当区块数量超过SM数量时,如何同步区块?

CUDA-GPU 规范:CC。6.1、3 SM、Windows 10、VS2015、GeForce MX150 显卡。请帮助我解决这个问题。我使用了很多代码,但没有一个起作用。

parallel-processing cuda gpu nvidia

2
推荐指数
1
解决办法
3524
查看次数

如何在 python 中记录 GPU 利用率

我一直在使用一个名为 GPUtil 的库来尝试将 GPU 的利用率百分比值记录在数组中。

我使用的命令输出了太多数据,无法添加到我的数组中。我只想要核心的利用率百分比。内存利用率与我无关。

这两个数组用于 PyQtgraph 中的图形

我写的函数如下所示:

import GPUtil
import time
time_x = []
gpu_y = []

def gpu_util_timer(self):
    for n in range(10):
        Graph_Util.gpu_y.append(GPUtil.showUtilization())
        Graph_Util.time_x.append(n)
        time.sleep(1)
    print('gpu done')
Run Code Online (Sandbox Code Playgroud)

此后,我采纳了以下建议并实施了它:

def N_gpu_util_timer(self):
    for n in range(10):
        GPUs = GPUtil.getGPUs()
        gpu_load = GPUs[0].load
        Graph.gpu_y.append(gpu_load)
        time.sleep(1)
    print(Graph.gpu_y)
    print('N gpu done')
Run Code Online (Sandbox Code Playgroud)

python gpu

2
推荐指数
1
解决办法
4780
查看次数

Nvidia GPU 可以启动多少个线程?

Nvidia GTX 1050 4GB GPU 可以启动多少个线程?例如:内核<<<1,32>>>(args); 可以启动 32 个线程。那么可能的最大线程数是多少?我知道这篇文章nvidia GTS 450 有多少线程

cuda gpu nvidia

2
推荐指数
1
解决办法
68
查看次数