SSE2 和内联装配插入结构
Posted
技术标签:
【中文标题】SSE2 和内联装配插入结构【英文标题】:SSE2 and inline assembly insert structur 【发布时间】:2019-06-06 21:00:30 【问题描述】:我已经开始学习混合使用 c 代码和 gcc 内联汇编的 SIMD 命令。我试图了解如何将结构中的值添加到浮动指针(xmm0)。我不知道,这样做的正确方法是什么。
我已经动态分配了一个结构并将其命名为 tmp。现在我希望 struct 的值仅使用 SSE2 指令添加到浮动指针。
#include <stdio.h>
#include <stdlib.h>
struct Test
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
test;
int main()
struct Test *tmp = malloc(sizeof(test));
tmp->a = 10;
tmp->b = 2;
tmp->c = 3;
tmp->d = 4;
asm ( "movapd [tmp], %%xmm0;"
);
free(tmp);
return 0;
编译此代码后,我会出现错误消息: " 错误:无效字符 '[' 开始操作数 1 `[tmp]' "
我想知道我做错了什么以及如何在浮动指针中插入结构的值。
【问题讨论】:
你看过可以代替内联汇编的Intel intrinsics吗? 我和其他人一起讨论not using inline asm,但如果你必须尝试asm ( "movapd (%0), %%xmm0;" : : "r"(tmp) : "xmm0" );
。这是 gcc 默认使用的 at&t 语法(另见 -masm=intel
)。它还使用 gcc 的 extended asm 约束来提供参数。
@DavidWohlferd:除了那不安全。你忘了How can I indicate that the memory *pointed* to by an inline ASM argument may be used?
@Biggy:如果你一开始还只是学习 SIMD 指令,我不明白你为什么要介绍学习如何使用 GNU C 内联 asm 语法的复杂性同时正确+安全。一旦你了解了 x86 asm 以及编译器的工作原理,它本身就已经够难了。甚至专家也会犯内联汇编错误,这可能导致与 SIMD 错误无关的难以调试的问题令人困惑。如果您想学习 SIMD asm,请在使用 SIMD 内部函数时查看编译器的 asm 输出。和/或在 asm 中手写整个函数,从编译器输出开始。
见How to remove "noise" from GCC/clang assembly output?
【参考方案1】:
sizeof(Test) == 4。这不能很好地与 movapd 一起使用!另请注意,对 malloc 的调用并不总是返回 16 字节对齐的内存,因此您可能希望使用 _mm_malloc (或等效的)。
添加到前面的 cmets,要么使用内在函数(并将代码扔到 Godbolt 中以查看生成的 ASM/机器代码),要么在 ASM 中编写整个方法。除了在 100 英尺远的地方像报纸一样可读,内联 ASM 不能在编译器之间移植,而且在某些编译器(例如 VC++)上根本不允许。内在函数是首选。
【讨论】:
在 C 语言中,您可以使用aligned_alloc
分配对齐的存储空间。它与free
兼容,与_mm_malloc
不同。以上是关于SSE2 和内联装配插入结构的主要内容,如果未能解决你的问题,请参考以下文章
结构建模设计——Solidworks软件之装配体操作基本总结一(装配体功能界面简介插入零件操作基本配合操作)