- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在将 MMX SSE 转换为等效的 C 代码。我几乎已经转换了它,但我得到的图像质量不合适,或者我可以看到图像中出现了一些噪音。我正在调试过去 5 天的代码,但我没有得到任何发生这种情况的原因。如果你们调查这个问题并帮助我解决问题,我将非常非常高兴。
原始 SSE 代码:
void unpack_8bit_to_16bit( __m128i *a, __m128i* b0, __m128i* b1 )
{
__m128i zero = _mm_setzero_si128();
b0 = _mm_unpacklo_epi8( a, zero );
b1 = _mm_unpackhi_epi8( a, zero );
}
void convolve_cols_3x3( const unsigned char* in, int16_t* out_v, int16_t* out_h, int w, int h )
{
using namespace std;
assert( w % 16 == 0 && "width must be multiple of 16!" );
const int w_chunk = w/16;
__m128i* i0 = (__m128i*)( in );
__m128i* i1 = (__m128i*)( in ) + w_chunk*1;
__m128i* i2 = (__m128i*)( in ) + w_chunk*2;
__m128i* result_h = (__m128i*)( out_h ) + 2*w_chunk;
__m128i* result_v = (__m128i*)( out_v ) + 2*w_chunk;
__m128i* end_input = (__m128i*)( in ) + w_chunk*h;
for( ; i2 != end_input; i0++, i1++, i2++, result_v+=2, result_h+=2 )
{
*result_h = _mm_setzero_si128();
*(result_h+1) = _mm_setzero_si128();
*result_v = _mm_setzero_si128();
*(result_v+1) = _mm_setzero_si128();
__m128i ilo, ihi;
unpack_8bit_to_16bit( *i0, ihi, ilo );
*result_h = _mm_add_epi16( ihi, *result_h );
*(result_h+1) = _mm_add_epi16( ilo, *(result_h+1) );
*result_v = _mm_add_epi16( *result_v, ihi );
*(result_v+1) = _mm_add_epi16( *(result_v+1), ilo );
unpack_8bit_to_16bit( *i1, ihi, ilo );
*result_v = _mm_add_epi16( *result_v, ihi );
*(result_v+1) = _mm_add_epi16( *(result_v+1), ilo );
*result_v = _mm_add_epi16( *result_v, ihi );
*(result_v+1) = _mm_add_epi16( *(result_v+1), ilo );
unpack_8bit_to_16bit( *i2, ihi, ilo );
*result_h = _mm_sub_epi16( *result_h, ihi );
*(result_h+1) = _mm_sub_epi16( *(result_h+1), ilo );
*result_v = _mm_add_epi16( *result_v, ihi );
*(result_v+1) = _mm_add_epi16( *(result_v+1), ilo );
}
}
下面给出了我转换的代码
void convolve_cols_3x3( const unsigned char* in, int16_t* out_v, int16_t* out_h, int w, int h )
{
using namespace std;
assert( w % 16 == 0 && "width must be multiple of 16!" );
const int w_chunk = w/16;
uint8_t* i0 = (uint8_t*)( in );
uint8_t* i1 = (uint8_t*)( in ) + w_chunk*1*16;
uint8_t* i2 = (uint8_t*)( in ) + w_chunk*2*16;
int16_t* result_h = (int16_t*)( out_h ) + 2*w_chunk*16;
int16_t* result_v = (int16_t*)( out_v ) + 2*w_chunk*16;
uint8_t* end_input = (uint8_t*)( in ) + w_chunk*h*16;
for( ; i2 != end_input; i0+= 16, i1+= 16, i2+= 16, result_v+= 16, result_h+= 16 )
{
for (int i=0; i<8;i++)
{
result_h[i] = 0;
result_h[i + 8] = 0;
result_v[i] = 0;
result_v[i + 8] = 0;
result_h[i] = (int16_t)(i0[i]) + result_h[i] ;
result_h[i + 8] = (int16_t)(i0[i + 8]) + result_h[i + 8] ;
result_v[i] = (int16_t)(i0[i]) + result_v[i] ;
result_v[i + 8] = (int16_t)(i0[i + 8]) + result_v[i + 8] ;
result_v[i] = (int16_t)(i1[i]) + result_v[i] ;
result_v[i + 8] = (int16_t)(i1[i + 8]) + result_v[i + 8] ;
result_v[i] = (int16_t)(i1[i]) + result_v[i] ;
result_v[i + 8] = (int16_t)(i1[i + 8]) + result_v[i + 8] ;
result_h[i] = result_h[i] - (int16_t)(i2[i]);
result_h[i + 8] = result_h[i + 8] - (int16_t)(i2[i + 8]);
result_v[i] = (int16_t)(i2[i]) + result_v[i] ;
result_v[i + 8] = (int16_t)(i2[i + 8]) + result_v[i + 8] ;
}
}
}
抱歉,如果代码不那么可读。 w
和 h
表示宽度和高度。 out_h
和 out_v
是两个参数,稍后用于其他目的。
最佳答案
这些错误似乎存在于您的指针数学和源数据的读取中。指针变量 i0、i1、i2 是 unsigned char。您的代码中类似这样的行:
result_h[i + 8] = (int16_t)(i0[i + 8]) + result_h[i + 8] ;
应该是这样的:
result_h[i + 8] = (int16_t)(i0[i*2 + 16]) + result_h[i + 8] ;
转换为 int16_t 不会影响 i0 方括号内的偏移量。您正在使用 16 字节结构 (__m128i),但以 8 字节偏移量访问它们。您还只使用 i0 和 i1 指向的整数的低 8 位。在原始的 SSE 代码中,您正在读取 16 位整数。如果您需要在加法之前读取 16 位整数,最终更正后的代码可能如下所示:
result_h[i + 8] = *(int16_t *)(&i0[i*2 + 16]) + result_h[i + 8];
关于c - MMX SSE 到 C 代码转换时图像质量下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12711101/
我试图淡化两个图像,但结果不是预期的(之前用 C 代码做过)。这是 MMX 代码: void fadeMMX(ImagenBMP *imagen1, ImagenBMP *imagen2, int f
当我查看最新处理器的图表和概述时[1],我从未看到提及 MMX 寄存器 MM0 - MM7。但从规范来看,它们似乎仍然存在。可以依赖它们出现在所有支持 SSE 的处理器中吗?除了更旧的 FPU 堆栈之
我正在尝试实现一个高性能的 C++ 程序,每个周期我将 8 个字节加载到 MMX 寄存器然后处理它们,但是当然我想在到达字符串末尾时停止。 所以这是我找到的解决方案,每个循环加载8个字节,每个字节与\
我正在尝试使用汇编语言对两个小数组执行简单的点积计算。这是我的代码: #include #include #include void fillArray(int16_t* a, int16_t*
在Wikipedia ,它说: 在 SSE2 中添加的整数支持使得 MMX 在很大程度上变得多余,尽管在某些情况下通过将 MMX 与 SSE 操作并行使用可以进一步提高性能。 这是否意味着处理器可以在
iPhone处理器ARMV6支持MMX指令吗? 最佳答案 简单的回答是否定的 - MMX 是一项英特尔技术。更长的答案是 ARM 支持 Neon SIMD instruction set 。它的架构与
我使用的是 2010 Enterprise,因此我拥有所有可用的建模工具。但我仍然很少使用它们。我自己编写对象、setter、getter...除了类图之外,我想开始使用建模。我应该选择 Delphi
我目前正在学习 Intel x86 处理器上的汇编编程。 有人可以向我解释一下,MMX 和 XMM 寄存器有什么区别吗?我很困惑它们的功能是什么以及它们之间的区别和相似之处? 最佳答案 MM寄存器是M
我想使用 MMX 指令集来优化我的 Linux C 程序,该程序对以 RGB 格式存储的图像执行大量操作(每个 RGB 分量存储在无符号字符中)。操作很简单:我将一幅图像与另一幅图像逐像素相减,然后累
据我了解,JIT 不会将 MSIL 编译成将在 x86 上使用 MMX 指令的 native 代码。如果这是真的(因为我很难找到有关此事的最新信息),那么我想要一种在我的代码中使用 MMX 的方法。我
问题: 我将 MMX 代码转换为相应的 SSE2 代码。我预计会有近 1.5 倍到 2 倍的加速。但是两者都花费了完全相同的时间。这是为什么? 场景: 我正在学习 SIMD 指令集及其性能比较。我进行
好吧,它们带来了(至少应该带来)性能的巨大提升,不是吗? 所以,我还没有看到任何 Linux 内核源代码,但很想问:它们以某种方式被使用了吗? (在这种情况下——对于没有此类指令的系统,必须有一些特殊
让我先介绍一下……我对 ASM 的经验极其有限,对 SIMD 的经验更甚。 但碰巧我有以下 MMX/SSE 优化代码,我想将其移植到 AltiVec 指令以在 PPC/Cell 处理器上使用。 这可能
我试图通过使用带有内联汇编的 MMX 和 SSE 指令集来优化一些算术。但是,我一直无法找到有关这些增强指令集的时序和用法的良好引用。你能帮我找到包含吞吐量、延迟、操作数以及指令简短描述信息的引用资料
我有这段代码: @combinerows: mov esi,eax and edi,Row1Mask and ebx,Row2Mask or ebx,edi /
我一直在阅读 x86 指令集扩展,它们似乎只在某些非常特定的情况下有用(例如 SSE3 中的 HADDPD - (Horizontal-Add-Packed-Double))。这些需要特定的寄存器
section .data qVar1: dq 1 section .bss var28: resb 28 section .text _main: ; Us
我正在将 MMX SSE 转换为等效的 C 代码。我几乎已经转换了它,但我得到的图像质量不合适,或者我可以看到图像中出现了一些噪音。我正在调试过去 5 天的代码,但我没有得到任何发生这种情况的原因。如
我希望有一种通用的方法来检测特定的 CPU 功能。对于此任务,我创建了此函数,该函数采用 EAX 叶编号、寄存器名称和位编号并返回 true 或 false。它适用于 MMX/SSEx/AVX (EA
以下代码: simd(n, is) long *is; { long i; asm("pxor %mm0,%mm0"); for (i = 0; i < n; i += W) {
我是一名优秀的程序员,十分优秀!