मैं एक परीक्षण कार्यक्रम है कि एक युक्ति है और आकार के एक मेजबान सरणी n कर्नेल कि n धागे जो आवंटित बनाता है पैदा करेगा और उसके बाद लांच बनाने हूँ डिवाइस सरणी में प्रत्येक स्थान पर निरंतर मान 0.95f। पूरा होने के बाद, डिवाइस सरणी होस्ट होस्ट में कॉपी की जाती है और सभी प्रविष्टियां कुल होती हैं और अंतिम कुल प्रदर्शित होता है।CUDA परिणाम बहुत बड़े सरणी का उपयोग कर कचरा दिखाए, लेकिन रिपोर्ट कोई त्रुटि
नीचे दिया गया कार्यक्रम लगभग 60 मिलियन फ्लोट तक सरणी आकारों के लिए ठीक काम करता है और सही परिणाम बहुत जल्दी देता है, लेकिन 70 मिलियन तक पहुंचने पर कार्यक्रम थोड़ी देर तक लटकता प्रतीत होता है और अंततः कुल के लिए एनएएन परिणाम देता है । 60 मिलियन रन के बाद मेजबान सरणी का निरीक्षण करना यह दिखाता है कि यह 0.95 एफ के साथ सही ढंग से आबादी वाला है, लेकिन 70 मिलियन रन के बाद यह जांच कर रहा है कि यह एनएएन के साथ आबादी वाला है। जहां तक मुझे पता है कि सीयूडीए में से कोई भी वापसी त्रुटियों को कॉल नहीं करता है।
मैं एक 2GB GT640m (कंप्यूट 3.0) का उपयोग कर रहा है, मुझे 1024 के एक अधिकतम ब्लॉक आकार और 2147483647
की एक अधिकतम ग्रिड आयाम मुझे यकीन है कि वहाँ कुछ इसी तरह प्राप्त करने के बेहतर तरीके हैं रहा हूँ दे रही है, और मैं करूंगा सुझाव सुनना पसंद है। लेकिन मैं यह भी समझना चाहूंगा कि यहां क्या गलत हो गया है, इसलिए मैं इससे सीख सकता हूं।
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <fstream>
void cudaErrorHandler(cudaError_t status)
{
// Cuda call returned an error, just print error for now
if(status != cudaSuccess)
{
printf("Error");
}
}
__global__ void addKernel(float* _Results, int _TotalCombinations)
{
// Get thread Id
unsigned int Id = (blockDim.x * blockDim.y * blockIdx.x) + (blockDim.x * threadIdx.y) + threadIdx.x;
//If the Id is within simulation range, log it
if(Id < _TotalCombinations)
{
_Results[Id] = 0.95f;
}
}
#define BLOCK_DIM_X 32
#define BLOCK_DIM_Y 32
#define BLOCK_SIZE BLOCK_DIM_X * BLOCK_DIM_Y // Statc block size of 32*32 (1024)
#define CUDA_CALL(x) cudaErrorHandler(x)
int main()
{
// The number of simulations to run
unsigned int totalCombinations = 45000000;
int gridsize = 1;
// Work out how many blocks of size 1024 are required to perform all of totalCombinations
for(unsigned int totalsize = gridsize * BLOCK_SIZE; totalsize < totalCombinations;
gridsize++, totalsize = gridsize * BLOCK_SIZE)
;
// Allocate host memory
float* host_results = new float[totalCombinations];
memset(host_results, 0, sizeof(float) * totalCombinations);
float *dev_results = 0;
cudaSetDevice(0);
// Allocate device memory
CUDA_CALL(cudaMalloc((void**)&dev_results, totalCombinations * sizeof(float)));
dim3 grid, block;
block = dim3(BLOCK_DIM_X, BLOCK_DIM_Y);
grid = dim3(gridsize);
// Launch kernel
addKernel<<<gridsize, block>>>(dev_results, totalCombinations);
// Wait for synchronize
CUDA_CALL(cudaDeviceSynchronize());
// Copy device data back to host
CUDA_CALL(cudaMemcpy(host_results, dev_results, totalCombinations * sizeof(float), cudaMemcpyDeviceToHost));
double total = 0.0;
// Total the results in the host array
for(unsigned int i = 0; i < totalCombinations; i++)
total+=host_results[i];
// Print results to screen
printf("Total %f\n", total);
delete[] host_results;
return 0;
}
आपकी त्रुटि प्रबंधन विधि काम नहीं कर रही है। इसे साबित करने के लिए, अपने ब्लॉक मंद x और y से 50 को बदलें (2500 धागे प्रदान करना, जो अवैध है) और आपको कोई त्रुटि मुद्रित नहीं होती है। यदि आप अपनी त्रुटि प्रबंधन को ठीक करते हैं, तो आप समस्या की खोज करेंगे। आपके विफलता बिंदु पर चीजें काम नहीं कर रही हैं यह है कि आपका ग्रिडाइज (आप 1 डी ग्रिड लॉन्च कर रहे हैं) एक्स आयाम (डिफ़ॉल्ट रूप से 65535) में अधिकतम ग्रिड आकार से अधिक है। यदि आप बड़े gridsize का लाभ लेना चाहते हैं, तो आपको '-arch = sm_30' स्विच के साथ संकलित करने की आवश्यकता है। एक और नोट, आपके पास 22 का ब्लॉक एक्स आयाम है, इसकी अनुशंसा नहीं की जाती है। –
@RobertCrovella मैंने अपनी त्रुटि जांच (और ब्लॉक एक्स, जो कि मेरे भाग पर एक टाइपो था) को सही किया और फिर कमांड लाइन पर स्विच जोड़ा और इससे मेरी समस्याएं हल हो गईं और सब ठीक से चल रहा है। यदि आप इसे उत्तर के रूप में सबमिट करना चाहते हैं तो मैं इसे स्वीकार करूंगा। – TVOHM