gpt4 book ai didi

gcc - 在 GCC 中编译 SSE 内在函数会出错

转载 作者:行者123 更新时间:2023-12-04 11:24:49 29 4
gpt4 key购买 nike

我的 SSE 代码在 Windows 平台上完全正常,但是当我在 Linux 上运行它时,我遇到了很多问题。其中之一是这样的:

这只是我的代码的示例说明:

int main(int ref, int ref_two)

{

__128i a, b;

a.m128i_u8[0] = ref;

b.m128i_u8[0] = ref_two;

.

.


.

.....

}

错误 1:

error : request for member 'm128i_u8' in something not a structure or union



在此线程中,它提供了使用适当的 _mm_set_XXX 内在函数而不是上述方法的解决方案,因为它仅适用于 Microsoft。
SSE intrinsics compiling MSDN code with GCC error?

我尝试了我在程序中替换了set指令的线程中提到的上述方法,但它严重影响了我的应用程序的性能。

我的代码很大,需要在 2000 处更改。所以我正在寻找更好的替代方案而不影响我的应用程序的性能。

最近我从英特尔那里得到了这个链接,上面说要使用 -fms-diaelect将其从 Windows 移植到 Linux 的选项。

http://software.intel.com/sites/products/documentation/doclib/iss/2013/compiler/cpp-lin/GUID-7A69898B-BDBB-4AA9-9820-E4A590945903.htm

有没有人试过上面的方法?有没有人找到将大代码移植到 Linux 的解决方案?

@Paul,这是我的代码,我放置了一个计时器来测量两种方法所花费的时间,结果令人震惊。

代码 1:115 毫秒(微软直接访问元素的方法)

代码 2:151 ms(使用 set 指令)

当我在我的代码中使用 set 时,它花费了我 36 毫秒。

注意:如果我在我的单条指令中替换它需要 36 毫秒,并且想象一下如果我在我的程序中替换它 2000 次我会得到性能下降。

这就是我正在寻找比 set 指令更好的替代方案的原因

代码 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);

}
}

代码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);

}
}

最佳答案

您正在尝试使用不可移植的 Microsoft 主义。只需坚持使用更便携的内在函数,例如_mm_set_epi8 :

 __128i a = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ref);
这将适用于所有平台和编译器。
如果您看到性能问题,那么可能是因为您在循环中执行了一些效率低下的操作——尽管无法就提高代码效率提出任何具体建议,但没有看到实际代码。
编辑
通常有更有效的方法来加载具有值组合的向量,例如在您的示例中,例如:
#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
}
}
这仅转化为 3 条指令。 (注意:如果您不能假设 SSE4.1 为最小值,那么 _mm_insert_epi8 可以用两个按位内在函数替换 - 这仍然比使用 _mm_set_epi8 更有效)。

关于gcc - 在 GCC 中编译 SSE 内在函数会出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22110916/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com