带有 CUDA 的 C++:如何将一个字节表示为一个字符或一组字符?
C++ with CUDA: how to express a byte as a char or set of chars?
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';
}
如何在 Cuda 内核中将字节转换为 char *
样式的字符串?
首先,不要对少量固定数量的 space 使用 malloc();使用数组。其次,不要切换,一般来说,在内核代码中,尽量避免分散控制路径。最后,如果它应该是 C 风格的字符串,它需要以 '[=11=]'
.
结尾
所以考虑这样的事情:
#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] = '[=10=]';
return sb;
}
请注意,我使用的是 C 风格编码而不是 "pimping up" class,因此您可以非常轻松地将此代码转换为正确的 C 语言。
这是我目前的解决方案,旨在避免矢量化代码中的流控制问题。
/*! \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
}
但是,基于库调用的解决方案最好。
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';
}
如何在 Cuda 内核中将字节转换为 char *
样式的字符串?
首先,不要对少量固定数量的 space 使用 malloc();使用数组。其次,不要切换,一般来说,在内核代码中,尽量避免分散控制路径。最后,如果它应该是 C 风格的字符串,它需要以 '[=11=]'
.
所以考虑这样的事情:
#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] = '[=10=]';
return sb;
}
请注意,我使用的是 C 风格编码而不是 "pimping up" class,因此您可以非常轻松地将此代码转换为正确的 C 语言。
这是我目前的解决方案,旨在避免矢量化代码中的流控制问题。
/*! \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
}
但是,基于库调用的解决方案最好。