【问题标题】:How is this variable value changing in the function?这个变量值在函数中是如何变化的?
【发布时间】:2019-01-02 15:23:52
【问题描述】:

我有这个代码:

device_params_t *device_params = malloc(sizeof(device_params_t));

get_device_params(device_params, platform_id, workWithUser ? "check_pdfs_user" : "check_pdfs_owner", program_buffer, program_size);

int password_len = strlen(password_prefix) + password_digits + strlen(password_suffix);

unsigned int prefix_length = strlen(password_prefix), suffix_length = strlen(password_suffix);
unsigned long count;

// while (number < max_password) {
    count = max_password - number;
    count = count > batch_size ? batch_size : count;
    printf("%lu\n", count);
    run_on_gpu(device_params, params, number, password_prefix, prefix_length, password_suffix, suffix_length, password_len, count, &found);
    printf("%lu\n", count);
    if (found) {
        // break;
    }
    number += count;
// }

这是 get_device_params 函数:

void get_device_params(device_params_t* params, cl_platform_id platform_id, const char *kernel_func, char *program_buffer, size_t program_size) {
    clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 0, NULL, &params->device_count);
    params->device_ids = (cl_device_id*) malloc(sizeof(cl_device_id) * params->device_count);
    int err = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, params->device_count, params->device_ids, NULL);
    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to create a device group! %d\n", err);
        free(params->device_ids);
        return;
    }

    int i;
    size_t local, min_local = 0;

    params->context = clCreateContext(NULL, params->device_count, params->device_ids, NULL, NULL, &err);
    if (err != CL_SUCCESS)
    {
        printf("Error: Failed to create a compute context!\n");
        goto out1;
    }

    cl_program program = build_program(params->context, params->device_ids, program_buffer, program_size);
    if (!program)
    {
        printf("Error: Failed to create compute program!\n");
        goto out1;
    }

    params->kernel = clCreateKernel(program, kernel_func, &err);
    if (!params->kernel || err != CL_SUCCESS)
    {
        printf("Error: Failed to create compute kernel!\n");
        goto out1;
    }

    params->commands = malloc(sizeof(cl_command_queue) * params->device_count);

    for(i = 0; i < params->device_count; i++) {
        params->commands[i] = clCreateCommandQueue(params->context, params->device_ids[i], 0, &err);
        if (!params->commands[i])
        {
            printf("Error: Failed to create a command commands! %d\n", err);
            goto out1;
        }

        err = clGetKernelWorkGroupInfo(params->kernel, params->device_ids[i], CL_KERNEL_WORK_GROUP_SIZE, sizeof(local), &local, NULL);
        if (err != CL_SUCCESS)
        {
            printf("Error: Failed to retrieve kernel work group info! %d\n", err);
            goto out1;
        }

        min_local = min_local > local ? local : min_local;
    }

    params->local = min_local;

    return;

    out1:
    if (params->kernel) {
        clReleaseKernel(params->kernel);
    }
    if (params->commands) {
        for(i = 0; i < params->device_count; i++) {
            clReleaseCommandQueue(params->commands[i]);
        }
    }
    if (params->context) {
        clReleaseKernel(params->context);
    }
    clReleaseProgram(program);

    return;
}

run_on_gpu 定义为:

void run_on_gpu(device_params_t *device_params, PDFParams *params, unsigned long start, char *prefix, unsigned int prefix_length, char *suffix, unsigned int suffix_length, int password_length, const unsigned long cnt, bool *found)
{
    printf("size %lu\n", cnt);
}

现在发生的事情是这样的:

9
size 549755813890
9

我希望它是:

9
size 9
9

不知道发生了什么!

【问题讨论】:

  • 你有printf("%lu"),然后是run_on_gpu,然后是另一个printf("%lu") - 看起来它正在做它应该做的事情?
  • @valiano 打印的值不同。 run_on_gpu 中的值为 549755813890,但预计为 9
  • 知道了。但是预期的输出不应该是9size 99吗?
  • 只是为了验证,password_length == cnt == 9?
  • @valiano 抱歉,已更新。不,password_length 是我后来添加的,粘贴时忘记撤消了。但结果如问题中所述

标签: c variables gcc memory opencl


【解决方案1】:

在 SWAG 中,run_on_gpu() 的使用和定义存在参数不匹配。 549755813890 在您将其视为 64 位十六进制数字之前并不是很有趣。此时它变为0x00000080:00000002,冒号插入在 32 位组之间。这只是让我尖叫,run_on_gpu() 中的参数 cnt 以某种方式覆盖了另外两个 32 位值。

值得注意的是,这将与 64 位系统上的 GCC 一致,但与任何平台上的 32 位 GCC 或 MSVC 不一致。据我所知,64 位 GCC 是唯一将 unsigned long 视为 64 位的“桌面”编译器,所有其他编译器都将其视为 32 位。

【讨论】:

  • 伟大的观察!在主机端,应该始终使用 cl_ 类型而不是“本机”类型;它们的设计尺寸与设备类型相同。
猜你喜欢
  • 2017-12-30
  • 2019-02-25
  • 1970-01-01
  • 2011-12-10
  • 1970-01-01
  • 2018-09-01
  • 2015-09-30
  • 1970-01-01
  • 2015-02-25
相关资源
最近更新 更多