有没有办法强制PMULHRSW将0x8000视为1.0而不是-1.0?

时间:2012-08-29 15:14:17

标签: image-processing assembly sse fixed-point

要处理8位像素,要做伽马校正而不丢失信息,我们通常会对值进行上采样,以16位或其他方式工作,然后将它们下采样到8位。

现在,这对我来说是一个新的领域,所以请原谅不正确的术语等。

根据我的需要,我选择使用“非标准”Q15,其中我只使用范围的上半部分(0.0-1.0),而0x8000代表1.0而不是-1.0。这使得在C中计算事物变得更加容易。

但我遇到了SSSE3的问题。它有PMULHRSW指令乘以Q15数字,但它使用Q15的“标准”范围是[-1,1-2 - 19],所以乘以(我的)0x8000(1.0)乘以0x4000(0.5)给出0xC000( - 0.5),因为它认为0x8000是-1。这很烦人。

我做错了什么?我应该将像素值保持在0000-7FFF范围内吗?难道这种失败的目的是它是一种定点格式吗?有没有解决的办法?也许有些技巧?

Q15上是否有某种明确的论文讨论了所有这些?

2 个答案:

答案 0 :(得分:3)

就个人而言,我会选择将最大值限制为0x7FFF(~0.99something)的解决方案。

  • 您不必通过箍来让处理器以您希望的方式工作
  • 您不必花费很长时间来记录您的“奇怪”代码的细节,因为0-0x7FFF的操作将立即为您的代码的读者所识别 - Q-format被理解(根据我的经验)从-1.0+1.0-one lsb。算术运算效果不好,因为1 lsb的值在0的每一侧都不同!

除非你能想象自己成功地向一组议论性代码审查人员争论说,额外的一点对于算法的运行至关重要,而不仅仅是“最后0.01%的性能”,坚持每个人都能理解的代码,并映射到您可用的硬件。


或者,重新安排您之前的操作,以便所有像素都与您最初的像素相反。或者采取以下操作来消除您之前发送的内容。然后使用Q15格式的-1.00.0的值。

答案 1 :(得分:2)

如果您确定不会使用任何“大于”$8000的数字,唯一的问题是当至少有一个乘数为$8000时(-1,尽管您希望它是1)。

在这种情况下,解决方案相当简单:

pmulhrsw xmm0, xmm1
psignw xmm0, xmm0

或者,在我们的案例中完全相同(谢谢,Peter Cordes!):

pmulhrsw xmm0, xmm1
pabsw xmm0, xmm0

这会将负值从–1乘以其正值。