如果你有一个输入数组和一个输出数组,但是你只想写那些通过某个条件的元素,那么在AVX2中这样做最有效的方法是什么?
我在SSE看到它是这样做的:(来自:https://deplinenoise.files.wordpress.com/2015/03/gdc2015_afredriksson_simd.pdf)
__m128i LeftPack_SSSE3(__m128 mask, __m128 val)
{
// Move 4 sign bits of mask to 4-bit integer value.
int mask = _mm_movemask_ps(mask);
// Select shuffle control data
__m128i shuf_ctrl = _mm_load_si128(&shufmasks[mask]);
// Permute to move valid values to front of SIMD register
__m128i packed = _mm_shuffle_epi8(_mm_castps_si128(val), shuf_ctrl);
return packed;
}
Run Code Online (Sandbox Code Playgroud)
这对于4宽的SSE来说似乎很好,因此只需要16个入口LUT,但对于8宽的AVX,LUT变得非常大(256个条目,每个32个字节或8k).
我很惊讶AVX似乎没有简化此过程的指令,例如带有打包的蒙版存储.
我想通过稍微改变来计算左边设置的符号位数,你可以生成必要的排列表,然后调用_mm256_permutevar8x32_ps.但这也是我认为的一些指示......
有没有人知道用AVX2做这个的任何技巧?或者什么是最有效的方法?
以下是上述文件中左包装问题的说明:
谢谢
在Visual Studio 2013中,存在一个新的调用约定_vectorcall.它适用于可以在SSE寄存器中传递的SSE数据类型.
您可以指定成员函数的调用约定,如此.
struct Vector{//a 16 byte aligned type
_m128i _vectorcall operator *(Vector a);
};
Run Code Online (Sandbox Code Playgroud)
这是有效的,它可以编译,并且尽管有16个对齐要求,类型也可以通过值传递.
另一方面,如果我尝试将它附加到任何构造函数(这似乎完全合乎逻辑),它就会失败.
struct Vector
_vectorcall Vector(SomeOtherTypeWith16Alignment a);
};
Run Code Online (Sandbox Code Playgroud)
编译器发出警告消息(我有警告错误):
警告C4166:构造函数/析构函数的非法调用约定.
强迫我将代码更改为:
struct Vector{
Vector(SomeOtherTypeWith16Alignment a); //fails to compile
};
Run Code Online (Sandbox Code Playgroud)
这也无法编译,因为现在SomeOtherTypeWith16Alignment不能通过值传递,因为在构造函数上未启用_vectorcall.
所以我被迫改变它.
struct Vector{
Vector(const SomeOtherTypeWith16Alignment& a);
};
Run Code Online (Sandbox Code Playgroud)
哪个编译.但它不再使用_vectorcall,可能不会传递SSE寄存器中的数据,因为我更喜欢......
所以基本上,为什么我不能指定构造函数使用的调用约定?
这可能是Visual C++特定的(_vectorcall当然是).我没有在其他编译器上试过这个 -
我想通过IACA分析器运行一些代码,以查看它使用了多少微指令-我从一个简单的函数开始,以查看它是否正常工作。
不幸的是,当我插入IACA说要使用的宏时,生成的程序集非常不同,因此对其进行任何分析都无济于事。
这是没有IACA生产的组装件
00007FF9CD590580 vaddps ymm1,ymm5,ymmword ptr [rax]
00007FF9CD590584 vaddps ymm2,ymm6,ymmword ptr [rax+20h]
00007FF9CD590589 vaddps ymm3,ymm7,ymmword ptr [rax+40h]
00007FF9CD59058E vmulps ymm4,ymm1,ymm1
00007FF9CD590592 vfmadd231ps ymm4,ymm2,ymm2
00007FF9CD590597 vfmadd231ps ymm4,ymm3,ymm3
00007FF9CD59059C vcmpgt_oqps ymm1,ymm4,ymm9
00007FF9CD5905A2 vrsqrtps ymm0,ymm4
00007FF9CD5905A6 vandps ymm2,ymm1,ymm0
00007FF9CD5905AA vmovups ymm3,ymm8
00007FF9CD5905AF vfmsub231ps ymm3,ymm2,ymm4
00007FF9CD5905B4 vmovups ymmword ptr [r9+rax],ymm3
00007FF9CD5905BA add rax,rcx
00007FF9CD5905BD sub r8d,1
00007FF9CD5905C1 jne fm::EvlOp::applyLoop<`RegisterShapeOps<fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> > >'::`2'::doDISTANCE_SPHERE_11,fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> >::DataWrapper,fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> >::RegisterBlock,fm::interpeter<fm::interpreter_settings<math::v8float,4,float,fm::Instruction,math::v8f2d,math::v8float> >::instruction_input>+0B0h (07FF9CD590580h)
Run Code Online (Sandbox Code Playgroud)
这是我添加IACA宏后产生的结果。(我正在测试MSVC产生的二进制文件,因此我按照手册中的说明使用IACA_VC64_START和IACA_VC64_END)。
00007FF9CD59058B vmovups ymm2,ymmword ptr [rax+40h]
00007FF9CD590590 vmovups ymm0,ymmword ptr [rax]
00007FF9CD590594 vmovups ymm1,ymmword ptr [rax+20h]
00007FF9CD590599 vaddps …Run Code Online (Sandbox Code Playgroud) 我有一个C++解决方案,总是忘记解决方案配置(调试与发布等),以及打开时的启动项目.
在启动时,它总是默认返回调试,并且没有启动项目.
这个数据用于保存正确,但几个月前它已停止运作.最初这是VS2013,但我在VS2015上,解决方案仍然没有保存这些数据.
我试过删除各种文件.
在解决方案文件夹中我删除了.sdf
在解决方案发布文件夹中有一个.suo我删除了
这些都没有解决问题.
我不知道这些信息保存在哪里,有谁知道如何解决这个问题?
谢谢