- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有以下问题,需要使用除AVX2以外的任何方法解决。
我在m128i变量中存储了3个值(不需要第4个值),并且需要将这些值移动4,3,5。我需要两个功能。一个用于这些值的右逻辑移位,另一个用于左逻辑移位。
有人知道使用SSE / AVX解决问题的方法吗?我唯一能找到的是_mm_srlv_epi32()
,它是AVX2。
要添加更多信息。这是我尝试使用SSE / AVX优化的代码。这是我的绘图/检查引擎的一部分。
uint32_t Board::getMoversBlack(){
const uint32_t nocc=~(BP|WP);
const uint32_t BK = BP & K;
uint32_t movers = (nocc >> 4) & BP;
movers |= ((nocc & MASK_R3) >>3) & BP;
movers |= ((nocc & MASK_R5) >>5) & BP;
if (BK != 0) {
movers |= (nocc << 4) & BK;
movers |= ((nocc & MASK_L3) << 3) & BK;
movers |= ((nocc & MASK_L5) <<5) & BK;
}
return movers;
}
最佳答案
如果确实需要此功能(并且无法通过重新排列数据来避免这种情况),则可以完全/安全地模拟_mm_srlv_epi32
,而不会破坏任何高位或低位。
对于编译时常量计数,您可以在大多数情况下混合使用左移和右移。
可能是错误的选择:
shrx
的x86可变计数移位具有笨拙的语义,并在Intel SnB系列上解码为多个微指令。他们还接受额外的mov
指令,以将移位计数放入cl
中(如果尚未存在)。pshufd
复制以从{0,22,0,0}
的起始 vector 中获取{11,22,33, 0}
的 vector ,然后重复{0,0,33,0}
。)movss
混合成一个 vector ,并将下半部分与movsd
混合。那些使用shuffle端口,因此shuffle吞吐量可能是个问题。这实际上可能非常可靠。__m128i srlv435_sse4(__m128i v)
{
__m128i rshift = _mm_srli_epi32(v, 3); // v >> 3
// differences in shift count by multiplying by powers of 2
__m128i vshift = _mm_mullo_epi32(rshift, _mm_setr_epi32(2,4,1,0)); // [ x >> 2, y >> 1, z >> 3, 0 ] Except with low bits truncated.
__m128i shift2 = _mm_srli_epi32(vshift, 2); // [ x >> 4, y >> 3, z >> 5, 0 ]
return shift2;
}
很好,因为它就地运行,即使没有AVX1,编译器也不需要任何MOVDQA指令来复制寄存器。
_mm_mullo_epi32
并不快:Haswell上p0的2微秒:10c延迟和每2c吞吐量一个。 Skylake上的吞吐量更高,其中两个uops都可以在p0或p1上运行,但仍依赖10c延迟。 (
http://agner.org/optimize/和
x86标签Wiki中的其他链接。)
pmulld
是单uup指令(〜5个周期,1c吞吐量),而不是10个周期的2个相关uop。
_mm_mul_epu32
一次进行2次乘法。为了排列奇数元素(1和3),
pshufd
将它们复制并拖曳到位置0和2,
pmuludq
在其中寻找它们。
// general case: substitute in *any* shift counts and it still works.
__m128i srlv_sse2(__m128i v) // [x y z w]
{
__m128i vs_even = _mm_mul_epu32(v, _mm_setr_epi32(1U<<1, 1U<<2, 1U<<0, 0)); // [ x<<1 z<<0 ] (64-bit elements)
// The 4 (1U<<2) is unused, but this lets us share a constant with the SSE4 version, saving rodata size. (Compilers optimize duplicate constants for you; check the disassembly for same address)
vs_even = _mm_srli_epi64(vs_even, 5); // [ x>>4 0 x>>5 0 ] (32-bit elements ready for blending with just an OR)
__m128i odd = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1));
__m128i vs_odd = _mm_mul_epu32(v, _mm_setr_epi32(1U<<(32-3),0,0,0)); // [ (y<<32) >> 3 0 ] (64-bit elements)
// If any elements need left shifts, you can't get them all the way out the top of the high half with a 32-bit power of 2.
//vs_odd = _mm_slli_epi64(vs_odd, 32 - (3+2)); // [ garbage, y>>3, 0, 0 ]
// SSE2 doesn't have blend instructions, do it manually.
__m128i vs_oddhi = _mm_and_si128(vs_odd, _mm_setr_epi32(0, -1, 0, -1));
__m128i shifted = _mm_or_si128(vs_even, vs_oddhi);
return shifted;
}
这里有一些明显的优化:
vs_odd = _mm_srli_epi32v, 3);
并将
0,-1,0,0
用作AND掩码。
movq
),但不比
movdqa
便宜(在带消除功能的CPU上)。
__m128i rshift = _mm_srli_epi32(v, 3); // v >> 3
__m128i xy00 = _mm_move_epi64(rshift);
__m128i vshift = _mm_add_epi32(rshift, xy00); // [ x >> 2, y >> 2, z >> 3, 0 ]
但这不能处理
y
。我们可以将
y>>2
与
vshift
隔离开,然后再次添加它以生成
y>>1
。 (但是请记住不要使用
y>>3
中的旧
xy00
)。
_mm_mul_epu32
(
pmuludq
)一次,然后使用copy + shift + AND进行下一步(从原始
v
而不是
rshift
复制以缩短dep链)。这在您的情况下很有用,因为您没有使用top元素,因此只有一个有效的奇数元素,因此不需要可变移位。
movq
,
movss
和
movsd
组合使用,基本上将3个元素分别移位可能会带来更多好处。在端口压力,延迟,uop计数(前端吞吐量)和其他方面之间需要权衡取舍。例如我在想
movdqa xmm1, xmm0
psrld xmm0, 3 # [ x>>3 y>>3 garbage ]
psrld xmm1, 4 # [ x>>4 y>>4 garbage ]
movss xmm1, xmm0 # [ x>>3 y>>4 garbage ] # FP shuffle
psrld xmm0, 2 # [ garbage z>>5 ]
movsd xmm0, xmm1 # [ x>>3 y>>4 z>>5 ] # FP shuffle
例如,Haswell的每个时钟吞吐量只有1个移位,因此这并不妙。与乘法选项相比,它具有相当好的延迟。在Skylake上很好,其中2个端口可以运行 vector 即时移位。
关于c++ - 使用非x86架构上的非AVX指令移位xmm整数寄存器值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46993981/
在 Windows 世界中,什么是正确的名称。具有导出函数的老式 C++ DLL?不是 COM DLL,也不是 .NET DLL。我们以前通过调用 LoadLibrary() 和 GetProcAdd
目前我正在使用javaEE7,我有一个场景如下。在我的 JSF Web 应用程序中,我有一个事件监听器(不是 JSF 事件),当事件调用时,它会执行某些操作,然后将这些信息更新到我的 Web 应用程序
这不是 AJAX 请求/响应回调问题... 我正在使用 Dojo 1.5 构建网格。我正在尝试 dojo.connect具有功能的扩展/收缩按钮。我的问题是 grid.startup()在创建实际 D
非 Webkit Opera 是 very specific在某些功能中,因此通常通过 JavaScript 检测到 the following way . 但是,Opera Next 几乎是 Goo
我已查看以下链接中给出的所有日志,但未能找到 IP 地址: https://developer.couchbase.com/documentation/server/3.x/admin/Misc/Tr
我有一个命令行程序,它根据一组源文件生成一个我想在我的 Android gradle 构建 (A) 中使用的 jar 文件。这个命令行程序只是将一个 jar 文件存储在磁盘上的一个目录中。 我如何创建
下面的 htaccess 命令将所有非 www 转移到 http www RewriteEngine On RewriteCond %{HTTP_HOST} !^www\. RewriteRule ^
我正在使用自定义链接器脚本将内核镜像分为两部分。第一个是普通代码和数据,第二个是初始化代码和不再需要时将被丢弃的数据。初始化部分也不像内核本身那样在地址空间之间共享,因此如果 fork() 仍然存在(
这个问题在这里已经有了答案: Several unary operators in C and C++ (3 个答案) What is the "-->" operator in C++? (29
假设我有一个类设置如下: class A { public: virtual void foo() { printf("default implementation\n"); } }; c
#include using namespace std; int main(int argc, char *argv[]) { int i=-5; while(~(i)) {
近期,百度搜索引擎变化无常,很多企业站、行业站、门户站、论坛等站点遭到了降权,特别是比比贴分类信息网直接遭到了拔毛,这对于广大站长来说是一种打击,也是各个企业、行业的打击。 至今,很多网站已经恢复
我现在正在使用 IBM TPM v1332 + IBM TSS v1470 并尝试将一些基本关键字/密码存储到 TPM 上的非 volatile 内存中。我找到了两种方法。一种是创建一个密封对象并使用
我的 PHP 脚本中有一个正则表达式,如下所示: /(\b$term|$term\b)(?!([^)/iu 这与 $term 中包含的单词匹配,只要前后有单词边界并且它不在 HTML 标记内即可。 但
我想显示用户名称地址(请参阅 www.ipchicken.com ),但我唯一能找到的是 IP 地址。我尝试了反向查找,但也没有用: IPAddress ip = IPAddress.Parse(th
只有 UI 线程能够显示到屏幕上,还是其他线程也可以这样做? 最佳答案 不,您只能直接从 UI 线程访问 UI,但您可以编码来自其他线程的结果,例如使用 Control.Invoke 或 contro
我正在使用现代 Excel 滚动条(不是旧的 ActiveX 类型,即开发人员 > 插入 > 表单控件 > 滚动条)并且想检测它的值何时更改。我找不到有关此类对象的更改事件的任何信息。您可以在单击时分
当我使用这段代码时 IE 6 确实正确使用了指定的样式表,但所有其他浏览器在应该使用基本上声明的样式表时会忽略这两种样式表,如果您不是 IE,请使用此样式表。 有什么想法吗? 最佳答案 n
我想指定 2 mssql 表之间的关系。 付款类别和付款。 paymentcategory.id 加入 payout.category 列。 在 payout.json 模型中 我指定为外键:id,
我正在尝试制作非 volatile UDF,但似乎不可能。因此,这是我非常简单的test-UDF: Option Explicit Dim i As Integer Sub Main() i = 0
我是一名优秀的程序员,十分优秀!