-2

我有一个名为 Product 的课程。

每个产品都有一个值,我想在 GPU 上添加这些值。我在主机端填充了我的阵列

int * h_A, * d_A;
    h_A = (int*) malloc(enterNum * sizeof(int));
    cudaMalloc((void **) &d_A, enterNum * sizeof(int));



    Product p("Product", price);

    h_A[i] = p.getValue();

    while (i < enterNum) {
        i++;
        cout << "Enter product name:";
        cin >> desc;
        cout << "Enter product price:";
        cin >> price;
        Product p("Product", price);

        h_A[i] = p.getValue();
    }


    cudaMemcpy(d_A, h_A, enterNum, cudaMemcpyHostToDevice);
    priceSum<<<enterNum, 1024>>>(d_A,enterNum,result);

    int  result2 = 0;

    cudaMemcpy(result, result2, enterNum, cudaMemcpyDeviceToHost);

这里 cudaMemcpy 函数给出错误,因为我不使用指针。我可以在这里做什么?我不需要在这里使用指针,不是吗?

这是我的求和函数:

__global__ void priceSum(int *dA, int count, int result) {

    int tid = blockIdx.x;

    if (tid < count){
        result+= dA[tid];
    }
}

完整代码:

using namespace std;
#include "cuda_runtime.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>

class Product {
private:
    char * description;
    int productCode;
    int value;
    static int lastCode;
public:
    Product(char* descriptionP, int valueP) {

        productCode = ++lastCode;
        value = valueP;
        description = new char[strlen(descriptionP) + 1];
        strcpy(description, descriptionP);
    }

    Product(Product& other) {
        productCode = ++lastCode;
        description = new char[strlen(other.description) + 1];
        strcpy(description, other.description);
    }

    ~Product() {
        delete[] description;
    }

    char* getDescription() const {
        return description;
    }

    void setDescription(char* description) {
        this->description = description;
    }

    int getValue() const {
        return value;
    }

    void setValue(int value) {
        this->value = value;
    }

};

int Product::lastCode = 1000;

__global__ void priceSum(int *dA, int count, int * result) {

    int tid = blockIdx.x;

    if (tid < count)
        result+= dA[tid];

}

int main(void) {

    int enterNum, price, * result = 0;
    string desc;
    const char * desc2;


    cout << "How many products do you want to enter?";
    cin >> enterNum;

    int * h_A, * d_A;
    h_A = (int*) malloc(enterNum * sizeof(int));
    cudaMalloc((void **) &d_A, enterNum * sizeof(int));



    int i = 0;

    while (i < enterNum) {

        cout << "Enter product name:";
        cin >> desc;
        cout << "Enter product price:";
        cin >> price;

        Product p("Product", price);
        h_A[i] = p.getValue();
        i++;
    }


    cudaMemcpy(d_A, h_A, enterNum * sizeof(int), cudaMemcpyHostToDevice);
    priceSum<<<enterNum, 1>>>(d_A,enterNum,result);

    int  result2 = 0;

    cudaMemcpy(&result2, result, enterNum, cudaMemcpyDeviceToHost);
    cout << result2;

    return 0;
}
4

1 回答 1

2

result您应该在主机代码中显示 的定义,但我认为它是:

int result;

基于你如何将它传递给你的priceSum内核。

您在这里有超过 1 个问题。

  1. 在您的priceSum内核中,您将 dA[] 中的值相加并将答案存储在result. 但是您已经通过而不是通过引用result将变量传递给内核,因此您正在修改的值对于函数来说是本地的,并且不会显示在其他任何地方。当 C 中的函数需要修改通过参数列表传递给它的变量,并且修改后的变量要显示在函数调用上下文中时,有必要通过引用(即使用指针)而不是传递该参数按价值。请注意,这是基于 C 编程语言的,并非特定于 CUDA。因此,您应该将内核定义重写为:

    __global__ void priceSum(int *dA, int count, int *result) {
    
  2. 关于您的 cudaMemcpy 调用,有几个问题需要清理。首先,我们需要result使用 cudaMalloc 正确创建存储空间(在调用内核之前,因为内核会在那里存储一些东西。)接下来,我们需要修复 cudaMemcpy 调用本身的参数列表。所以你的主机代码应该重写为:

    cudaMemcpy(d_A, h_A, enterNum, cudaMemcpyHostToDevice);
    int *result;
    cudaMalloc((void **)&result, sizeof(int));
    priceSum<<<enterNum, 1024>>>(d_A,enterNum,result);
    
    int  result2 = 0;
    
    cudaMemcpy(&result2, result, sizeof(int), cudaMemcpyDeviceToHost);
    
  3. 您的代码似乎还有其他问题,围绕线程和块的数据分组。但是你没有展示足够多的程序让我理解它。因此,让我指出您的代码仅显示result(and result2) 的单个值,但是按照内核的编写方式,每个线程都会将其值添加dA[tid]到 to result。您不能让一堆线程都在没有控制机制的情况下更新全局内存中的单个值,并期望获得合理的结果。像这样的问题通常最好使用经典的并行缩减算法来处理,但为了简单起见,为了尝试让某些东西正常工作,您可以使用atomics

    atomicAdd(result, dA[tid]);
    
  4. 对不起,但你的内核根本没有意义。您正在使用blockIdx.x作为tid变量,但请注意,对于特定 block 中的每个线程blockIdx.x来说,这是一个相同的数字。因此,继续以这种方式添加每个线程是没有意义的。我相信如果您将内核调用更改为:dA[tid]result

    priceSum<<<enterNum, 1>>>(d_A,enterNum,result);
    
于 2013-04-04T03:51:40.440 回答