C++ 将短包装/解包成整数

C++ 将短包装/解包成整数,c++,c,cuda,bit-manipulation,c++-amp,C++,C,Cuda,Bit Manipulation,C++ Amp,我想把两个有符号16位整数打包/解包成一个32位整数。然而,我并没有让它完全发挥作用 你知道我可能做错了什么吗 template <typename T> int read_s16(T& arr, int idx) restrict(amp) { return static_cast<int>((arr[idx/2] >> ((idx % 2) * 16)) << 16) >> 16; } template<ty

我想把两个有符号16位整数打包/解包成一个32位整数。然而,我并没有让它完全发挥作用

你知道我可能做错了什么吗

template <typename T>
int read_s16(T& arr, int idx) restrict(amp)
{
    return static_cast<int>((arr[idx/2] >> ((idx % 2) * 16)) << 16) >> 16;
}

template<typename T>
void write_s16(T& arr, int idx, int val) restrict(amp)
{
    // NOTE: arr is zero initialized
    concurrency::atomic_fetch_or(&arr[idx/2], (static_cast<unsigned int>(val) & 0xFFFF) << ((idx % 2) * 16));
}

下面的代码在MSVC中运行良好。如您所见,原则上它与您的代码相同。

问题可能是您忘记将数组的内容初始化为零?您的平台如何处理负数和转换为无符号整数

template <typename T>
int read_s16(T& arr, int idx)
{
    return static_cast<int>((arr[idx/2] >> ((idx % 2) * 16)) << 16) >> 16;
}

template<typename T>
void write_s16(T& arr, int idx, int val)
{
    // NOTE: arr is zero initialized
    arr[idx/2] |= (static_cast<unsigned int>(val) & 0xFFFF) << ((idx % 2) * 16);
}

int main()
{
    int ar[2] = { 0,0 }; // container

    write_s16<int [2]>(ar, 0, -16);
    write_s16<int [2]>(ar, 1, 5);

    assert(read_s16<int [2]>(ar, 0) == -16);
    assert(read_s16<int [2]>(ar, 1) == 5);

    return 0;
}
模板
内部读取(T&arr,内部idx)
{
返回静态_cast((arr[idx/2]>>((idx%2)*16))>16;
}
模板
无效写入(T&arr、int idx、int val)
{
//注意:arr初始化为零

arr[idx/2]|=(static_cast(val)&0xFFFF)它看起来太复杂了,里面有一些奇怪的操作

通常,你会这样做:

int32_t Pack(int16_t a, int16_t b)
{
   return (int32_t)((((uint32_t)a)<<16)+(uint32_t)b);
}

int16_t UnpackA(int32_t x)
{
   return (int16_t)(((uint32_t)x)>>16);
}

int16_t UnpackB(int32_t x)
{
   return (int16_t)(((uint32_t)x)&0xffff);
}
int32\u t包(int16\u t a、int16\u t b)
{
报税表(a)16 ;;
}
int16_t解包(int32_t x)
{
返回(int16_t)((uint32_t)x)和0xffff);
}

注意,我使用了显式位大小的类型来说明发生了什么。我也冒昧地假设你想要一个“整数”,而不是一个“无符号整数”。

< P>在C++ AMP中的这些原子操作也有以下限制:

  • 您不应该混合原子和正常(非原子)读写。 正常读取可能看不到原子写入的结果 内存位置。正常写入不应与原子写入混合 到相同的内存位置。如果您的程序不符合 这些标准将导致未定义的结果
  • 原子的 操作并不意味着任何类型的内存隔离。原子操作 可以重新排序。这与联锁的行为不同 C++中的操作
您似乎违反了其中的第一条。

请尝试以下打包方法:

int_32 = (int16_1 & 0x0000FFFF) | (int16_2 & 0xFFFF0000);
对于拆包:

int16_MSB = (int_32 >> 16) & 0xFFFF;
int16_LSB = int_32 & 0xFFFF;

你能举一些输入和输出的例子吗?me内部的一些东西反对将数据同时打包到单个
int
…Kerrek SB:代码在GPU上运行。你只是想存储它们并将它们传递给其他人吗?你如何处理这些符号?你能把它放到uint16\u t[2]中吗?从你的问题看来,你只是在打包它们,所以我建议使用无符号数据。数据是有符号的,这使得这有点复杂,它必须放入无符号整数或整数数组。嗯,在cpu上运行时,它对我也有效,在gpu上中断。可能是gpu处理右移符号差rently.Ade当然是正确的。有关原子学的任何其他问题,请参阅包含以下信息和其他信息的博客帖子:
int16_MSB = (int_32 >> 16) & 0xFFFF;
int16_LSB = int_32 & 0xFFFF;