Ste*_*eve 7 x86 gcc sse intel simd
我的SSE代码在Windows平台上运行得很好,但是当我在Linux上运行时,我遇到了很多问题.其中一个是:
这只是我的代码的示例说明:
int main(int ref, int ref_two)
{
__128i a, b;
a.m128i_u8[0] = ref;
b.m128i_u8[0] = ref_two;
.
.
.
.....
}
Run Code Online (Sandbox Code Playgroud)
错误1:
错误:请求成员'm128i_u8'不是结构或联合
在这个线程中,它提供了使用适当的_mm_set_XXX内在函数而不是上述方法的解决方案,因为它只适用于Microsoft. SSE内在函数编译带有GCC错误的MSDN代码?
我尝试了我在程序中替换set指令的线程中提到的上述方法,但它严重影响了我的应用程序的性能.
我的代码很庞大,需要在2000个地方更改.所以我在寻找更好的替代方案,而不会影响我的应用程序的性能.
最近我从英特尔获得了这个链接,它说使用-fms-diaelect选项将它从Windows移植到Linux.
有没有人尝试过上述方法?有没有人找到将大型代码移植到Linux的解决方案?
@Paul,这是我的代码,我已经放置了一个计时器来测量两种方法所花费的时间,结果令人震惊.
代码1:115毫秒(直接访问元素的Microsoft方法)
代码2:151 ms(使用设置指令)
当我在代码中使用set时,它花了我36毫秒.
注意:如果我在我的单个指令中替换它需要36毫秒,并想象如果我在我的程序中将它替换2000次,性能会降低.
这就是我寻找除设定指令之外的更好选择的原因
代码1:
__m128i array;
unsigned char* temp_src;
unsigned char* temp_dst;
for (i=0; i< 20; i++)
{
for (j=0; j< 1600; j+= 16)
{
Timerstart(&x);
array = _mm_loadu_si128 ((__m128i *)(src));
array.m128i_u8[0] = 36;
y+ = Timerstop(x);
_mm_store_si128( (__m128i *)temp_dst,array);
}
}
Run Code Online (Sandbox Code Playgroud)
代码2:
__m128i array;
unsigned char* temp_src;
unsigned char* temp_dst;
for (i=0; i< 20; i++)
{
for (j=0; j< 1600; j+= 16)
{
Timerstart(&x);
array = _mm_set_epi8(*(src+15),*(src+14),*(src+13),*(src+12),
*(src+11),*(src+10),*(src+9), *(src+8),
*(src+7), *(src+6), *(src+5), *(src+4),
*(src+3), *(src+2), *(src+1), 36 );
y+ = Timerstop(x);
_mm_store_si128( (__m128i *)temp_dst,array);
}
}
Run Code Online (Sandbox Code Playgroud)
您正在尝试使用非便携式Microsoft-ism.坚持使用更便携的内在函数,例如_mm_set_epi8:
__128i a = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ref);
Run Code Online (Sandbox Code Playgroud)
这适用于所有平台和编译器.
如果你看到性能问题那么可能是因为你在循环中做了一些低效的事情 - 没有看到实际的代码,尽管不可能提出任何关于提高代码效率的具体建议.
通常有更有效的方法来加载具有值组合的向量,例如在您的示例中,例如:
#include "smmintrin.h" // SSE4.1
for (...)
{
for (...)
{
__m128i v = _mm_loadu_si128(0, (__m128i *)src); // load vector from src..src+15
v = _mm_insert_epi8(v, 0, 36); // replace element 0 with constant `36`
_mm_storeu_si128((__m128i *)dst, v); // store vector at dst..dst+15
}
}
Run Code Online (Sandbox Code Playgroud)
这仅转换为3条指令.(注意:如果你不能假设SSE4.1最小,则_mm_insert_epi8可以用两个按位内在函数替换 - 这仍然比使用更有效_mm_set_epi8).