Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing 有没有办法强制PMULHRSW将0x8000视为1.0而不是-1.0?_Image Processing_Assembly_Sse_Fixed Point - Fatal编程技术网

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

Image processing 有没有办法强制PMULHRSW将0x8000视为1.0而不是-1.0?,image-processing,assembly,sse,fixed-point,Image Processing,Assembly,Sse,Fixed Point,为了处理8位像素,为了在不丢失信息的情况下进行gamma校正,我们通常会对值进行上采样,以16位或其他方式工作,然后将其下采样到8位 现在,这对我来说是一个有点新的领域,所以请原谅不正确的术语等 出于我的需要,我选择在“非标准”Q15中工作,其中我只使用范围的上半部分(0.0-1.0),0x8000表示1.0而不是-1.0。这使得用C语言计算东西变得容易得多 但是我遇到了SSSE3的问题。它有将Q15数字相乘的PMULHRSW指令,但它使用Q15的“标准”范围为[-1,1-2]⁻¹⁵], 所以将

为了处理8位像素,为了在不丢失信息的情况下进行gamma校正,我们通常会对值进行上采样,以16位或其他方式工作,然后将其下采样到8位

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

出于我的需要,我选择在“非标准”Q15中工作,其中我只使用范围的上半部分(0.0-1.0),0x8000表示1.0而不是-1.0。这使得用C语言计算东西变得容易得多

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

我做错了什么?我应该将像素值保持在0000-7FFF范围内吗?这不是违背了它作为定点格式的目的吗?有没有办法解决这个问题?也许有一些技巧


有没有关于Q15的权威性论文讨论过这一切?

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

  • 你不必急着让处理器按你喜欢的方式工作
  • 你不必花很长时间来记录你的“怪异”代码的来龙去脉,因为在0-0x7FFF上操作会立即被你的代码的读者识别——这是可以理解的(以我的经验)从
    -1.0
    运行到
    +1.0-one lsb
    。否则,该算法不会运行得很好,因为0的每一侧的1 lsb值不同
除非你能想象自己成功地向一组有争议的代码评审员证明,额外的一位对算法的运行至关重要,而不仅仅是“最后0.01%的性能”,否则请坚持每个人都能理解的代码,并将其映射到可用的硬件



或者,重新安排您以前的操作,使所有像素都显示为您最初拥有的负片。或者执行以下操作以接收您以前发送的负片。然后使用Q15格式的
-1.0
0.0

如果您确定不使用任何数字“大于”8000美元,唯一的问题是至少有一个乘数是8000美元(–1,尽管您希望它是1)

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

pmulhrsw xmm0, xmm1
psignw xmm0, xmm0
或者,在我们的案例中完全相同(谢谢,彼得·科德斯!)


这将使负值从乘以
-1
恢复为正值。

好吧,你可以在处理0x8000时加入一个特殊情况。除此之外,我不知道。我知道,但是紧密内环中的特殊情况扼杀了速度优势,加上同时处理4个通道比这是值得的。它可能仍然比C代码快。它只需要一个移位和一个pblendvb。或者它实际上是正确的,始终和0x7FFF?我也遇到了这个问题,我同意这是相当恼人的。这是AltiVec正确的一个例子,SSE被破坏(IMNVHO)。我在加权平均方案中成功地使用了预乘值。左侧的值在
0
0x7fff
范围内,表示权重从
0.0
1.0
(精确),另一边是要加权的值,它们是通常小于1.0的任意数字。我将这些值乘以系数32768.0/32767.0(这基本上相当于将大于2^14的每个值加1)实际上,由于PMULHRSW的四舍五入,在整个范围内没有精度损失。这可能就是我最后要做的。这意味着PMULHRSW不能乘以1.0,所以结果总是偏向黑色().SSSE3可能也能工作(作为副本和abs)。它将结果格式化为无符号整数,因此
0x8000
角盒在
pabsw
psignw
中保持为
0x8000
,如果它是乘法的结果。(如果可能的话)。
pmulhrsw xmm0, xmm1
pabsw xmm0, xmm0