2017-02-23 2 views
0

Я новичок в CUDA и GPGPU. Я пытаюсь проверить свойства большого набора чисел (больше, чем 32 бит), и я хотел бы попробовать сделать это с помощью моего Windows 7 64-битной машине, снабженной с NVidia GTX 1080:Используйте индекс потока CUDA как число

Detected 1 CUDA Capable device(s) 

Device 0: "GeForce GTX 1080" 
    CUDA Driver Version/Runtime Version   8.0/8.0 
    CUDA Capability Major/Minor version number: 6.1 
    Total amount of global memory:     8192 MBytes (8589934592 bytes) 
    (20) Multiprocessors, (128) CUDA Cores/MP:  2560 CUDA Cores 
    GPU Max Clock rate:       1734 MHz (1.73 GHz) 
    Memory Clock rate:        5005 Mhz 
    Memory Bus Width:        256-bit 
    L2 Cache Size:         2097152 bytes 
    Maximum Texture Dimension Size (x,y,z)   1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384) 
    Maximum Layered 1D Texture Size, (num) layers 1D=(32768), 2048 layers 
    Maximum Layered 2D Texture Size, (num) layers 2D=(32768, 32768), 2048 layers 
    Total amount of constant memory:    65536 bytes 
    Total amount of shared memory per block:  49152 bytes 
    Total number of registers available per block: 65536 
    Warp size:          32 
    Maximum number of threads per multiprocessor: 2048 
    Maximum number of threads per block:   1024 
    Max dimension size of a thread block (x,y,z): (1024, 1024, 64) 
    Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535) 
    Maximum memory pitch:       2147483647 bytes 
    Texture alignment:        512 bytes 
    Concurrent copy and kernel execution:   Yes with 2 copy engine(s) 
    Run time limit on kernels:      Yes 
    Integrated GPU sharing Host Memory:   No 
    Support host page-locked memory mapping:  Yes 
    Alignment requirement for Surfaces:   Yes 
    Device has ECC support:      Disabled 
    CUDA Device Driver Mode (TCC or WDDM):   WDDM (Windows Display Driver Model) 
    Device supports Unified Addressing (UVA):  Yes 
    Device PCI Domain ID/Bus ID/location ID: 0/1/0 
    Compute Mode: 
    < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) > 

Когда я бегу следующий код значения для «суммы» бессмыслен (28, 20 и т.д.), даже если я могу видеть ThreadId от 0 до 4095:

#include <cuda.h> 
#include <cuda_runtime.h> 
#include "device_launch_parameters.h" 
#include "stdio.h" 

__global__ void Simple(unsigned long long int *sum) 
{ 
    unsigned long long int blockId = blockIdx.x + blockIdx.y * gridDim.x + gridDim.x * gridDim.y * blockIdx.z; 

    unsigned long long int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z) 
     + (threadIdx.z * (blockDim.x * blockDim.y)) 
     + (threadIdx.y * blockDim.x) 
     + threadIdx.x; 

    printf("threadId = %llu.\n", threadId); 
    // Check threadId for property. Possibly introduce a grid stride for loop to give each thread a range to check. 
    sum[0]++; 
} 

int main(int argc, char **argv) 
{ 
    unsigned long long int sum[] = { 0 }; 

    unsigned long long int *dev_sum; 

    cudaMalloc((void**)&dev_sum, sizeof(unsigned long long int)); 
    cudaMemcpy(dev_sum, sum, sizeof(unsigned long long int), cudaMemcpyHostToDevice); 

    dim3 grid(2, 1, 1); 
    dim3 block(1024, 1, 1); 

    printf("--------- Start kernel ---------\n\n"); 
    Simple <<< grid, block >>> (dev_sum); 
    cudaDeviceSynchronize(); 

    cudaMemcpy(sum, dev_sum, sizeof(unsigned long long int), cudaMemcpyDeviceToHost); 

    printf("sum = %llu.\n", sum[0]); 

    cudaFree(dev_sum); 

    getchar(); 

    return 0; 
} 

Как я могу изменить этот вызов ядра, чтобы получить максимум потоки для работы (с моей настройкой) в диапазоне чисел говорят от 0 до 10^12, добавляя цикл шага сетки?

dim3 grid(2, 1, 1); 
dim3 block(1024, 1, 1); 

Simple <<< grid, block >>> (dev_sum); 
+2

Замените 'sum [0] ++' на 'atomicAdd (& sum [0], 1)'. – tera

+1

У вас есть состояние гонки на приращении – OutOfBound

+0

Спасибо. Это помогает. Можете ли вы ответить на вторую половину вопроса, задав максимальное количество потоков для работы с большим набором данных 1D? – munga

ответ

2

Все темы занимают приращение в одном и том же месте в памяти, что приводит к состоянию гонки. Вот почему результат неверен. Вы должны использовать атомное добавление, чтобы иметь это право (для CUDA есть функция).

+0

Спасибо. Эта помощь. Могли бы вы ответить на вторую половину вопроса, задав максимальное количество потоков для работы с большим набором данных 1D? – munga

Смежные вопросы