【发布时间】:2016-01-07 01:29:59
【问题描述】:
有谁知道 cub::scan 支持的最大尺寸是多少?我得到了超过 5 亿输入大小的核心转储。我想确保我没有做错任何事......
这是我的代码:
#define CUB_STDERR
#include <stdio.h>
#include "cub/util_allocator.cuh"
#include "cub/device/device_scan.cuh"
#include <sys/time.h>
using namespace cub;
bool g_verbose = false; // Whether to display input/output to console
CachingDeviceAllocator g_allocator(true); // Caching allocator for device memory
typedef int mytype;
/**
* Solve inclusive-scan problem
*/
static void solve(mytype *h_in, mytype *h_cpu, int n)
{
mytype inclusive = 0;
for (int i = 0; i < n; ++i) {
inclusive += h_in[i];
h_cpu[i] = inclusive;
}
}
static int compare(mytype *h_cpu, mytype *h_o, int n)
{
for (int i = 0; i < n; i++) {
if (h_cpu[i] != h_o[i]) {
return i + 1;
}
}
return 0;
}
/**
* Main
*/
int main(int argc, char** argv)
{
cudaSetDevice(0);
struct timeval start, end;
int num_items = 1073741824;
const int repetitions = 5;
mytype *h_in, *h_out, *h_cpu;
const int size = num_items * sizeof(mytype);
// Allocate host arrays
h_in = (mytype *)malloc(size);
h_out = (mytype *)malloc(size);
h_cpu = (mytype *)malloc(size);
// Initialize problem and solution
for (int i = 0; i < num_items; i++) {
h_in[i] = i;
h_out[i] = 0;
h_cpu[i] = 0;
}
solve(h_in, h_cpu, num_items);
// Allocate problem device arrays
mytype *d_in = NULL;
CubDebugExit(g_allocator.DeviceAllocate((void**)&d_in, sizeof(mytype) * num_items));
// Initialize device input
CubDebugExit(cudaMemcpy(d_in, h_in, sizeof(mytype) * num_items, cudaMemcpyHostToDevice));
// Allocate device output array
mytype *d_out = NULL;
CubDebugExit(g_allocator.DeviceAllocate((void**)&d_out, sizeof(mytype) * num_items));
// Allocate temporary storage
void *d_temp_storage = NULL;
size_t temp_storage_bytes = 0;
CubDebugExit(DeviceScan::InclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items));
CubDebugExit(g_allocator.DeviceAllocate(&d_temp_storage, temp_storage_bytes));
// Run
gettimeofday(&start, NULL);
for (long i = 0; i < repetitions; i++)
DeviceScan::InclusiveSum(d_temp_storage, temp_storage_bytes, d_in, d_out, num_items);
cudaThreadSynchronize();
gettimeofday(&end, NULL);
double ctime = end.tv_sec + end.tv_usec / 1000000.0 - start.tv_sec - start.tv_usec / 1000000.0;
cudaMemcpy(h_out, d_out, sizeof(mytype) * num_items, cudaMemcpyDeviceToHost);
int cmp = compare(h_cpu, h_out, num_items);
printf("%d\t", num_items);
if (!cmp)
printf("\t%7.4fs \n", ctime);
printf("\n");
if (h_in) delete[] h_in;
if (h_out) delete[] h_out;
if (h_cpu) delete[] h_cpu;
if (d_in) CubDebugExit(g_allocator.DeviceFree(d_in));
if (d_out) CubDebugExit(g_allocator.DeviceFree(d_out));
if (d_temp_storage) CubDebugExit(g_allocator.DeviceFree(d_temp_storage));
printf("\n\n");
return 0;
}
【问题讨论】:
-
您使用的是什么 GPU,它有多少内存?另外,您正在对什么类型执行扫描?
-
我正在使用 TitanX,它有 12GB。我正在执行独占设备扫描。
-
您对什么数据类型执行扫描?
int,float,double, ... ?你有多少主机内存? -
Here 是在大小为 1073741824(超过 10 亿个元素)的
int数组上的 cub::ExclusiveSum 的工作示例。它是在具有 64GB 主机内存和 K40c(也有 12GB)的 RHEL 6.2 系统上使用 CUDA 7.0 和 CUB 1.4.1 完成的。最终,如果您没有遇到内存分配错误,那么 cub 应该能够处理最多适合int num_items变量的最大正数 - 大约 20 亿个元素。但是在达到这个数字之前,内存限制可能会发挥作用,特别是取决于您使用的数据类型。 -
我正在处理 32 位整数,它适用于 268435456 个元素,但在此之上我得到分段错误(核心转储)。对于 64 位整数,它仅适用于 134217728 个整数,并且对于高于此的任何内容,我都会得到相同的错误。我正在使用 CubDebugExit 进行分配设备输入/输出,所以如果它与内存分配有关,我必须得到更有意义的错误消息吗?
标签: cuda nvidia cub prefix-sum