是否可以访问mmx寄存器中的单个字节,如数组?我有这个代码:
movq mm1,vector1
movq mm2,vector2
psubw mm1,mm2
Run Code Online (Sandbox Code Playgroud)
我想把mm1 [1],mm1 [2],mm1 [3] ....放到c ++变量中,比如:
int a,b=0;
mov a,mm1[1]
mov b,mm1[2]
Run Code Online (Sandbox Code Playgroud)
谢谢.
我正在尝试使用SIMD优化此功能,但我不知道从哪里开始.
long sum(int x,int y)
{
return x*x*x+y*y*y;
}
Run Code Online (Sandbox Code Playgroud)
反汇编函数如下所示:
4007a0: 48 89 f2 mov %rsi,%rdx
4007a3: 48 89 f8 mov %rdi,%rax
4007a6: 48 0f af d6 imul %rsi,%rdx
4007aa: 48 0f af c7 imul %rdi,%rax
4007ae: 48 0f af d6 imul %rsi,%rdx
4007b2: 48 0f af c7 imul %rdi,%rax
4007b6: 48 8d 04 02 lea (%rdx,%rax,1),%rax
4007ba: c3 retq
4007bb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
Run Code Online (Sandbox Code Playgroud)
调用代码如下所示:
do {
for (i = 0; i < maxi; i++) { …Run Code Online (Sandbox Code Playgroud) 什么更有效,为什么?
具体地_mm_loadu_si128与_mm_load_si128在C.
(编者注:或者这是标记的程序集,可能它们意味着movdqu与movdqa手写的asm.这是不一样的,特别是没有AVX,因为_mm_load_si128可以编译成ALU指令的内存操作数而根本没有单独movdqa的.)
我使用vs2012并想测试SSE和AVX的效率.SSE和AVX的代码几乎相同,只是SSE使用_m128而AVX使用_m256.我期望AVX代码比SSE代码快两倍,但测试结果显示它们的速度几乎相同.
我尝试选择/ arch:AVX或/ arch:SSE或/ NOT SET并注释SSE代码或注释AVX代码,无论我测试什么,SSE代码使用的时间约为2138ms,AVX代码约为2106ms.外部for循环仅用于增加循环时间,
#include "testfun.h"
#include <iostream>
#include <time.h>
#include <malloc.h>
#include "immintrin.h"
using namespace std;
#define dataLen 800000
void testfun()
{
float *buf1 = reinterpret_cast<float*>(_aligned_malloc( sizeof(float)*dataLen, 32 ));
float *buf2 = reinterpret_cast<float*>(_aligned_malloc( sizeof(float)*dataLen, 32 ));
for(int i=0; i<dataLen; i++)
{
buf1[i] = 1;
buf2[i] = 1;
}
double timePassed;
int t = clock();
float sum = 0;
//=========================SSE CODE=====================================
__m128 *p1 = (__m128 *)buf1;
__m128 *p2 = (__m128 *)buf2;
__m128 _result = _mm_set_ps1(0.0f);
for(int j=0;j<10000; j++) …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用sse加速我的代码,以下代码运行良好.基本上__m128变量应该指向一行中的4个浮点数,以便一次执行4个操作.
此代码等同于计算c[i]=a[i]+b[i]与i从0向3.
float *data1,*data2,*data3
// ... code ... allocating data1-2-3 which are very long.
__m128* a = (__m128*) (data1);
__m128* b = (__m128*) (data2);
__m128* c = (__m128*) (data3);
*c = _mm_add_ps(*a, *b);
Run Code Online (Sandbox Code Playgroud)
但是,当我想要移动我使用的数据(见下文)时,为了c[i]=a[i+1]+b[i]使用ifrom 0来计算3,它会在执行时崩溃.
__m128* a = (__m128*) (data1+1); // <-- +1
__m128* b = (__m128*) (data2);
__m128* c = (__m128*) (data3);
*c = _mm_add_ps(*a, *b);
Run Code Online (Sandbox Code Playgroud)
我的猜测是,它与__m128为128位且浮点数据为32位这一事实有关.因此,128位指针可能无法指向不能被128整除的地址.
无论如何,你知道问题是什么以及如何绕过它吗?
(注意,在Neon我使用这种数据类型以避免处理16位数据类型之间的转换)
为什么实践中"内移"中的"左移"是"向右移"?
// Values contained in a
// 141 138 145 147 144 140 147 153 154 147 149 146 155 152 147 152
b = vshlq_n_u32(a,8);
// Values contained in b
// 0 141 138 145 0 144 140 147 0 154 147 149 0 155 152 147
b = vshrq_n_u32(a,8);
// Values contained in b
// 138 145 147 0 140 147 153 0 147 149 146 0 152 147 152 0
Run Code Online (Sandbox Code Playgroud)
我记得在使用时会发现相同的情况_mm_slli_si128(虽然不同但是换班后的结果如下所示:
// …Run Code Online (Sandbox Code Playgroud) GCC和Clang编译器似乎采用了一些黑暗魔法.该C代码只是否定了双重的价值,但汇编指令涉及逐位XOR和指令指针.有人可以解释发生了什么,为什么它是一个最佳解决方案.谢谢.
test.c的内容:
void function(double *a, double *b) {
*a = -(*b); // This line.
}
Run Code Online (Sandbox Code Playgroud)
生成的汇编程序指令:
(gcc)
0000000000000000 <function>:
0: f2 0f 10 06 movsd xmm0,QWORD PTR [rsi]
4: 66 0f 57 05 00 00 00 xorpd xmm0,XMMWORD PTR [rip+0x0] # c <function+0xc>
b: 00
c: f2 0f 11 07 movsd QWORD PTR [rdi],xmm0
10: c3 ret
Run Code Online (Sandbox Code Playgroud)
(clang)
0000000000000000 <function>:
0: f2 0f 10 06 movsd xmm0,QWORD PTR [rsi]
4: 0f 57 05 00 00 …Run Code Online (Sandbox Code Playgroud) 我试图使用SSE内部函数优化我的代码.在浏览完文档后,我发现__m128SSE中有浮点变量的数据类型,能够存储4个浮点数.__m128dSSE2中只有一个能够存储2个浮点数吗?这些变量有什么区别?SSE2不应该比SSE快吗?
我现在正在使用向量和矩阵,有人建议我应该使用SSE而不是使用float数组.然而,在阅读C内在函数和汇编指令的定义时,看起来有一些函数的不同版本,其中向量必须是"16字节对齐",而较慢的版本,其中向量未对齐.矢量是16字节对齐的意思是什么?如何确保我的向量是16字节对齐的?
我正在使用_mm_extract_epi8 (__m128i a, const int imm8)函数,它有const int参数.当我编译此c ++代码时,收到以下错误消息:
错误C2057预期的常量表达式
__m128i a;
for (int i=0; i<16; i++)
{
_mm_extract_epi8(a, i); // compilation error
}
Run Code Online (Sandbox Code Playgroud)
我怎么能在循环中使用这个功能?