C++ 将短包装/解包成整数
我想把两个有符号16位整数打包/解包成一个32位整数。然而,我并没有让它完全发挥作用 你知道我可能做错了什么吗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
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;