如何有效地规范化CUDA中的矩阵列?
我的矩阵存储在column-major中,典型大小为2000x200.
该操作可以用以下matlab代码表示.
A = rand(2000,200);
A = exp(A);
A = A./repmat(sum(A,1), [size(A,1) 1]);
Run Code Online (Sandbox Code Playgroud)
这可以通过Thrust,cuBLAS和/或cuNPP有效地完成吗?
包括4个内核的快速实现如下所示.
想知道这些是否可以在1或2个内核中完成以提高性能,尤其是对于由cublasDgemv()实现的列求和步骤.
#include <cuda.h>
#include <curand.h>
#include <cublas_v2.h>
#include <thrust/device_vector.h>
#include <thrust/device_ptr.h>
#include <thrust/transform.h>
#include <thrust/iterator/constant_iterator.h>
#include <math.h>
struct Exp
{
__host__ __device__ void operator()(double& x)
{
x = exp(x);
}
};
struct Inv
{
__host__ __device__ void operator()(double& x)
{
x = (double) 1.0 / x;
}
};
int main()
{
cudaDeviceSetCacheConfig(cudaFuncCachePreferShared);
cublasHandle_t hd;
curandGenerator_t rng;
cublasCreate(&hd);
curandCreateGenerator(&rng, CURAND_RNG_PSEUDO_DEFAULT);
const size_t m = 2000, …Run Code Online (Sandbox Code Playgroud) 我有一个大小为50000x100的矩阵,我需要在C++中使用Cuda对每一行进行排序.我的架构是K80 NVidia卡.
由于列数很少,我目前正在内核中运行排序算法.我正在使用在矩阵的所有行上运行的修改后的气泡算法.
我想知道是否有更有效的方法继续进行.我试图在我的内核中使用thrust :: sort但速度要慢得多.我也尝试了合并排序算法,但算法的递归部分在我的内核中不起作用.
== ==编辑
这是我的内核:
__global__ void computeQuantilesKernel(float *matIn, int nRows, int nCols, int nQuantiles, float *outsideValues, float *quantilesAve, int param2)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
float values[100];//big enough for 100 columns
int keys[100];
int nQuant[100];//big enough for 100 quantiles (percentiles)
float thisQuantile[100];
int quant;
if (idx >= nRows) return;
//read matIn from global memory
for (int i = 0; i < nCols; i++)
{
values[i] = matIn[idx * nCols + i …Run Code Online (Sandbox Code Playgroud) 我正在评估CUDA并且目前使用Thrust库对数字进行排序.
我想为thrust :: sort创建我自己的比较器,但它会大幅减速!我只是从functional.h复制代码,创建了自己较少的实现.然而,它似乎以其他方式编译并且工作非常缓慢.
我正在使用Visual Studio 2010.我应该怎样做才能获得与选项1相同的性能?
完整代码:
#include <stdio.h>
#include <cuda.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/generate.h>
#include <thrust/sort.h>
int myRand()
{
static int counter = 0;
if ( counter++ % 10000 == 0 )
srand(time(NULL)+counter);
return (rand()<<16) | rand();
}
template<typename T>
struct less : public thrust::binary_function<T,T,bool>
{
__host__ __device__ bool operator()(const T &lhs, const T &rhs) const {
return lhs < rhs;
} …Run Code Online (Sandbox Code Playgroud) 我读到过有关 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)
我感到困惑的是:
thrust,这样我就可以做一个ifto threadIdx;如果没有,块中的线程如何相互通信,以确保对推力的调用已完成,并且它们应该忽略它(这似乎有点想象,因为没有系统的方法来确保用户的代码)。总结一下,当我thrust::device在内核中调用带参数的推力函数时到底发生了什么?