C ++ с CUDA: как выразить байт как символ или набор символов? - PullRequest
0 голосов
/ 29 сентября 2018

ВНУТРИ ЯДРА CUDA

Предположим, у меня есть байт, который может иметь двоичное значение от 0 до 255.

У меня есть массив символов (char *)длина три:

char * c = (char *) malloc(300000000*sizeof(char)); // 30 mb

Если не считать следующего (как, я хотел бы исключить «решения», которые включают ручной байт для представления символа):

switch(my_byte){
    case 0:
       c[0] = '0';
    case 1:
       c[1] = '1';
    ...
    case 255:
       c[0] = '2';
       c[1] = '5';
       c[2] = '5';
}

Как сделатьПреобразовать байт в строку стиля char * в ядре Cuda?

Ответы [ 2 ]

0 голосов
/ 30 сентября 2018

Это мое решение, пока я пытаюсь избежать проблемы управления потоком в векторизованном коде.

/*! \brief byte to raw chars; this is not a string! */
__device__ void byte_to_chars(uint8_t b,char * str_arr_ptr){
  uint8_t buf[4];

  buf[0] = b / 100;
  buf[1] = (b % 100 - b % 10) / 10;      
  buf[2] = b % 10;

  buf[3] = 3 - !buf[0] + !buf[0]*!buf[1]; // size

  // buf[3] = sz
  // 3 - buf[3] = missing digits; i.e., 1 for 023, 2 for 003
  for(int i = 0; i < buf[3]; i++) str_arr_ptr[0][i] = buf[ i + 3 - buf[3] ]+'0';              

  // modify function signature as needed -- i.e., return
  // useful info 
}

Тем не менее, решение на основе библиотечных вызовов было бы лучше.

0 голосов
/ 30 сентября 2018

Во-первых, не используйте malloc () для небольшого фиксированного пространства;использовать массив.Во-вторых, не переключайтесь, и вообще, в коде ядра, старайтесь избегать расходящихся путей управления.Наконец, если предполагается, что это строка в стиле C, она должна заканчиваться '\0'.

. Рассмотрим что-то вроде:

#include <cstdint>

enum { max_digits = 3, modulus = 10 };
struct stringized_byte_t {
    char[max_digits+1] buffer;
}

stringized_byte_t stringize_a_byte(uint8_t my_byte)
{
    uint8_t digits[max_digits];
    uint8_t num_digits = 1;

    uint8_t remainder = my_byte;
    while(remainder >= modulus) {
       uint8_t dividend = remainder / modulus;
       digits[num_digits - 1] = remainder - dividend * modulus;
       num_digits++;
       remainder = dividend;
    }

    // at this point we have one digit left (although it might be 0),
    // and we know the overall number of digits, so:

    digits[num_digits - 1] = remainder;

    // Now we need to flip the digit direction to fit the printing order,
    // and terminate the string

    stringized_byte_t sb;
    for(int i = 0; i < num_digits; i++) {
       sb.buffer[i] = '0' + digits[num_digits - i - 1];
    }
    sb.buffer[num_digits] = '\0';
    return sb;
}

Примечание. Я использовал кодирование в стиле Cчем «раскрутить» класс, так что вы можете очень легко преобразовать этот код в правильный C.

...