使用 GPU 添加数组元素的所有组合
Adding all combinations of array elements using GPU
我是 CUDAfy 编程的新手,在计算数组中所有元素组合的总和时遇到问题。我似乎想不出适合移植到 GPU 上的算法。
非常感谢任何帮助或任何类型的算法。
串口版代码如下:
for (int i = 0; i < Array.Count - 1; i++)
{
for (int j = (i + 1); j < Array.Count; j++)
{
ans.Add(Array.ElementAt(i) + Array.ElementAt(j));
}
}
除了一次添加之外,这不会给 GPU 太多工作。在您看到好处之前,阵列必须相当大。不管怎样:
我用的是C++,不熟悉C#和CUDAfy,但是逻辑移植应该很容易。存储数组中每对元素之和的核函数是:
template<typename T>
__global__ void sum_combinations_of_array( const T* arr, const size_t len, T* dest )
{
const int tx = blockIdx.x*blockDim.x+threadIdx.x;
const int ty = blockIdx.y*blockDim.y+threadIdx.y;
if( tx < len && ty < len && tx < ty ) {
dest[tx*len+ty] = arr[tx]+arr[ty];
}
}
您只是使用 2D 线程块来决定要添加数组的哪些元素(它们只是取代代码中的 i
和 j
)。 arr
的大小应至少为 len
,dest
的大小应至少为 len*len
。设置所有这些的主机代码 运行 类似于:
const int len = 1000;
int* arr;
cudaMalloc( &arr, len*sizeof(int) );
int* matrix;
cudaMalloc( &matrix, len*len*sizeof(int) );
// cudaMalloc2D could also be used here, but then you'll
// have to pay attention to the pitch
cudaMemset( matrix, 0, len*len*sizeof(int) );
// copy host array to arr with cudaMemcpy
// ...
const int numThreads = ???; // depends on your hardware
dim3 grid( len, (len+numThreads-1)/numThreads ), threads( 1, numThreads );
sum_combinations_of_array<int><<<grid,threads>>>( arr, len, matrix );
cudaDeviceSynchronize(); // wait for completion
// copy device matrix to host with cudaMemcpy (or cudaMemcpy2D)
// remember any element i<=j will be 0
// ...
cudaFree( arr );
cudaFree( matrix );
我是 CUDAfy 编程的新手,在计算数组中所有元素组合的总和时遇到问题。我似乎想不出适合移植到 GPU 上的算法。 非常感谢任何帮助或任何类型的算法。
串口版代码如下:
for (int i = 0; i < Array.Count - 1; i++)
{
for (int j = (i + 1); j < Array.Count; j++)
{
ans.Add(Array.ElementAt(i) + Array.ElementAt(j));
}
}
除了一次添加之外,这不会给 GPU 太多工作。在您看到好处之前,阵列必须相当大。不管怎样:
我用的是C++,不熟悉C#和CUDAfy,但是逻辑移植应该很容易。存储数组中每对元素之和的核函数是:
template<typename T>
__global__ void sum_combinations_of_array( const T* arr, const size_t len, T* dest )
{
const int tx = blockIdx.x*blockDim.x+threadIdx.x;
const int ty = blockIdx.y*blockDim.y+threadIdx.y;
if( tx < len && ty < len && tx < ty ) {
dest[tx*len+ty] = arr[tx]+arr[ty];
}
}
您只是使用 2D 线程块来决定要添加数组的哪些元素(它们只是取代代码中的 i
和 j
)。 arr
的大小应至少为 len
,dest
的大小应至少为 len*len
。设置所有这些的主机代码 运行 类似于:
const int len = 1000;
int* arr;
cudaMalloc( &arr, len*sizeof(int) );
int* matrix;
cudaMalloc( &matrix, len*len*sizeof(int) );
// cudaMalloc2D could also be used here, but then you'll
// have to pay attention to the pitch
cudaMemset( matrix, 0, len*len*sizeof(int) );
// copy host array to arr with cudaMemcpy
// ...
const int numThreads = ???; // depends on your hardware
dim3 grid( len, (len+numThreads-1)/numThreads ), threads( 1, numThreads );
sum_combinations_of_array<int><<<grid,threads>>>( arr, len, matrix );
cudaDeviceSynchronize(); // wait for completion
// copy device matrix to host with cudaMemcpy (or cudaMemcpy2D)
// remember any element i<=j will be 0
// ...
cudaFree( arr );
cudaFree( matrix );