我对AVX2功能上的英特尔Intrinsics有一个非常奇怪的错误,我想在这里分享.不管是我做错了什么(我现在还不能看到什么),或者库中的错误.
我在main.c中有这个简单的代码:
__int64 test = 0xFFFF'FFFF'FFFF'FFFF;
__m256i ymm = _mm256_set_epi64x(0x0000'0000'0000'0000,
0x0000'0000'0000'0000,
0x0000'0000'0000'0000,
test);
Run Code Online (Sandbox Code Playgroud)
赋给变量ymm的值是出于某种奇怪的原因:
ymm.m256i_i64[0] = 0xffff'ffff'ffff'ffff
ymm.m256i_i64[1] = 0x0000'0000'0000'0000
ymm.m256i_i64[2] = 0x0000'ffff'0000'0000
ymm.m256i_i64[3] = 0x0000'0000'0000'0000
Run Code Online (Sandbox Code Playgroud)
此时我已经调试了好几个小时,但看不出为什么ymm.m256i_i64[2]会得到这个流氓价值.请帮忙!
有趣/奇怪的事实: 如果我写这个C代码:
__m256i ymm = _mm256_set_epi64x(0x0000'0000'0000'0000,
0x0000'0000'0000'0000,
0x0000'0000'0000'0000,
0xFFFF'FFFF'FFFF'FFFF);
Run Code Online (Sandbox Code Playgroud)
然后将值正确设置为:
ymm.m256i_i64[0] = 0xffff'ffff'ffff'ffff
ymm.m256i_i64[1] = 0x0000'0000'0000'0000
ymm.m256i_i64[2] = 0x0000'0000'0000'0000
ymm.m256i_i64[3] = 0x0000'0000'0000'0000
Run Code Online (Sandbox Code Playgroud)
注意:我使用的是Visual Studio; 他们的编译器和调试工具,如下图所示:

打印代码后的printf : ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 ff ff ff 00 ff ff 00 00 …
总结/ tl; dr:有没有办法按位旋转YMM寄存器中的一个字节(使用AVX),而不是进行2x移位并将结果混合在一起?
对于YMM寄存器中的每8个字节,我需要在其中左旋7个字节.每个字节需要比前者更向左旋转一个位.因此,1字节应旋转0位,第7字节旋转6位.
目前,我做了一个实现,通过[我在这里使用1位旋转作为示例]将寄存器1位向左移位,并将7向右移位.然后我使用混合操作(内部操作_mm256_blend_epi16)从第一个和第二个临时结果中选择正确的位以获得我的最终旋转字节.
每个字节总共需要2个移位操作和1个混合操作,并且需要旋转6个字节,因此每个字节有18个操作(移位和混合具有几乎相同的性能).
必须有一种更快的方法来做到这一点,而不是使用18个操作来旋转单个字节!
此外,我需要在新寄存器中组装所有字节.我通过将带有"set"指令的7个掩码加载到寄存器中来完成此操作,因此我可以从每个寄存器中提取正确的字节.我和这些掩码与寄存器一起从中提取正确的字节.然后,我将单字节寄存器一起异或,以获得具有所有字节的新寄存器.这需要总共7 + 7 + 6次操作,因此另外20次操作(每个寄存器).
我可以使用提取内在函数(_mm256_extract_epi8)来获取单个字节,然后使用_mm256_set_epi8来组合新的寄存器,但我还不知道是否会更快.(英特尔内在指南中没有列出这些功能的性能,所以也许我在这里误解了一些内容.)
这给每个寄存器总共38次操作,这似乎不是在寄存器内以不同方式旋转6个字节的最佳值.
我希望有更多精通AVX/SIMD的人可以在这里指导我 - 无论我是以错误的方式解决这个问题 - 因为我觉得我现在可能正在这样做.
'到目前为止,我已经能够在我的 C 项目中使用数字分隔符。它们都已经用MSVC编译器编译过了,没有任何问题。
我刚刚改为使用 GCC 编译器,它不允许这些数字分隔符,并且当我使用它们时会抛出错误。我认为原因是因为 Visual Studio 对 C 和 C++ 使用相同的编译器,并且在 C++14 中(我相信),'允许使用数字分隔符。
如果是这种情况,GCC 中是否有可用的数字分隔符?当使用二进制的 64 位寄存器值时,这些分隔符确实很有帮助......
在昨天编写一些代码的时候,我遇到了两个奇怪的问题,我和我的函数编程导向的朋友都不知道.我们已经看了很长时间,并在网上研究过它,但我们无法在任何地方找到任何答案,所以这里有:
问题是在这段代码中:
第一个奇怪的问题:
let outer1 (bs : byte array) =
let rec inner (bs : byte array) (bacc : byte array) (i : int) =
match i with
| bs.Length -> bacc // <--- Error: bs is not recognized. Why?
| _ -> bacc.[i] <- bs.[i]
inner bs bacc (i + 1)
inner bs (Array.zeroCreate bs.Length) 0
Run Code Online (Sandbox Code Playgroud)
这里的问题是:FS0039: The namespace or module 'bs' is not defined.
这怎么可能?毕竟bs在函数签名中.而且,在let bsLength = bs.Length工作之前定义一个新的值match.但通过这样做,我看到了一个新的怪异:
let outer2 (bs : byte …Run Code Online (Sandbox Code Playgroud) 我希望有精通 React Native 的人可以帮助我。
我想根据图像所在视图的尺寸调整图像大小。据我了解,这应该可以通过使用“ResizeMode:Contain”作为图像上的样式来实现。这应该会导致图像重新缩放以适应周围的视图,如果它太大(根据我的理解)。
我附上了一张显示视图尺寸的图像(蓝色边框视图)。根据视图上的蓝色边框,视图的尺寸是正确的,但图像的大小不会调整以适合它。
有人能弄清楚,我在这里做错了什么,或者我在框架中遇到了错误吗?(我认为这是一个相当新的框架,所以我想这实际上可能会发生)。
如果有帮助,那么我目前正在使用以下React Native版本: react-native:0.54.4 (以及react-native-cli:2.0.1)。
avx ×2
c ×2
avx2 ×1
c++ ×1
compiler-bug ×1
f# ×1
gcc ×1
intrinsics ×1
react-native ×1
reactjs ×1
simd ×1
sse ×1