天道酬勤,学无止境

sse4

MOVDQU 指令 + 页边界(MOVDQU instruction + page boundary)

问题 我有一个简单的测试程序,它加载一个 xmm 寄存器,其中 movdqu 指令跨页面边界访问数据(OS = Linux)。 如果映射了以下页面,则效果很好。 如果它没有被映射,那么我会得到一个 SIGSEGV,这可能是意料之中的。 然而,这大大降低了未对齐负载的有用性。 此外,允许未对齐内存引用的 SSE4.2 指令(如 pcmpistri)似乎也表现出这种行为。 一切都很好——除了有很多使用 pcmpistri 的 strcmp 实现,我发现它们似乎根本没有解决这个问题——而且我已经能够设计出会导致这些实现失败的琐碎测试用例,而一次字节的简单 strcmp 实现将在相同的数据布局下正常工作。 还有一点要注意——似乎 64 位 Linux 的 GNU C 库实现有一个 __strcmp_sse42 变体,它似乎以更安全的方式使用 pcmpistri 指令。 这个 strcmp 的实现相当复杂,但它似乎很小心地试图避免页面边界问题。 我不确定这是否是由于我上面描述的问题,或者这是否只是尝试通过对齐数据来获得更好性能的副作用。 无论如何,我的问题主要是——我在哪里可以找到更多关于这个问题的信息? 我已经输入了“movdqu 跨越页面边界”以及我能想到的所有变体到谷歌,但没有遇到任何特别有用的东西。 如果有人能指出我有关这方面的更多信息,将不胜感激。 回答1 首先

2021-12-10 16:51:05    分类:技术分享    linux   sse4

SSE42 & STTNI - PcmpEstrM 比 PcmpIstrM 慢两倍,这是真的吗?(SSE42 & STTNI - PcmpEstrM is twice slower than PcmpIstrM, is it true?)

问题 我正在试验 SSE42 和 STTNI 指令并得到了奇怪的结果 - PcmpEstrM (使用显式长度字符串)比 PcmpIstrM (隐式长度字符串)运行慢两倍。 在我的i7 3610QM 上,差异是2366.2 ms 与 1202.3 ms - 97% 。 在i5 3470 上差异不是很大,但仍然很显着 = 3206.2 ms vs. 2623.2 ms - 22% 。 两者都是“常春藤桥” - 奇怪的是它们有如此不同的“差异”(至少我看不出它们的规格有任何技术差异 - http://www.cpu-world.com/Compare_CPUs/Intel_AW8063801013511,Intel_CM8063701093302 /)。 英特尔 64 位和 IA-32 架构优化参考手册提到了 PcmpEstrM 和 PcmpIstrM 的相同吞吐量 = 11 和延迟 = 3。 因此,我预计两者的性能相似。 问:差异是我实际设计/预期的还是我以错误的方式使用这些指令? 下面是我的虚拟测试场景(VS 2012)。 逻辑非常简单 - 扫描 16MB 的文本以找到匹配的字符。 由于 haystack 和 Needle string 都不包含零终止符 - 我希望 E 和 I 都具有相似的性能。 PS:我尝试在英特尔的开发论坛上发布这个问题,但他们将其识别为垃圾邮件:(

2021-11-27 23:24:18    分类:技术分享    c++   performance   sse   sse4

MOVDQU instruction + page boundary

I have a simple test program that loads an xmm register with the movdqu instruction accessing data across a page boundary (OS = Linux). If the following page is mapped, this works just fine. If it's not mapped then I get a SIGSEGV, which is probably expected. However this diminishes the usefulness of the unaligned loads quite a bit. Additionally SSE4.2 instructions (like pcmpistri) which allow for unaligned memory references appear to exhibit this behavior as well. That's all fine -- except there's many an implementation of strcmp using pcmpistri that I've found that don't seem to address this

2021-11-24 17:25:34    分类:问答    linux   sse4

对于 memcmp,SSE4.2 字符串指令比 SSE2 快多少?(How much faster are SSE4.2 string instructions than SSE2 for memcmp?)

问题 这是我的代码的汇编程序 你能把它嵌入到 C++ 中并检查 SSE4 吗? 速度 我很想看看是如何踏入SSE4的开发的。 还是根本不担心他? 让我们检查一下(我没有 SSSE3 以上的支持) { sse2 strcmp WideChar 32 bit } function CmpSee2(const P1, P2: Pointer; len: Integer): Boolean; asm push ebx // Create ebx cmp EAX, EDX // Str = Str2 je @@true // to exit true test eax, eax // not Str je @@false // to exit false test edx, edx // not Str2 je @@false // to exit false sub edx, eax // Str2 := Str2 - Str; mov ebx, [eax] // get Str 4 byte xor ebx, [eax + edx] // Cmp Str2 4 byte jnz @@false // Str <> Str2 to exit false sub ecx, 2 // dec 4 { AnsiChar : sub ecx, 4 } jbe @@true // ecx <= 0

2021-11-23 03:42:48    分类:技术分享    assembly   x86   sse   micro-optimization   sse4

SSE42 & STTNI - PcmpEstrM is twice slower than PcmpIstrM, is it true?

I'm experimenting with SSE42 and STTNI instructions and have got strange result - PcmpEstrM (works with explicit length strings) runs twice slower than PcmpIstrM (implicit length strings). On my i7 3610QM the difference is 2366.2 ms vs. 1202.3 ms - 97%. On i5 3470 difference is not so huge, but is still significant = 3206.2 ms vs. 2623.2 ms - 22%. Both are "Ivy Bridge" - it is strange that they have so different "difference" (at least i can't see any technical differences in their specs - http://www.cpu-world.com/Compare_CPUs/Intel_AW8063801013511,Intel_CM8063701093302/). Intel 64 and IA-32

2021-11-20 17:14:28    分类:问答    c++   performance   sse   sse4

How much faster are SSE4.2 string instructions than SSE2 for memcmp?

Here is my code's assembler Can you embed it in c ++ and check against SSE4? At speed I would very much like to see how stepped into the development of SSE4. Or is not worried about him at all? Let's check (I do not have support above SSSE3) { sse2 strcmp WideChar 32 bit } function CmpSee2(const P1, P2: Pointer; len: Integer): Boolean; asm push ebx // Create ebx cmp EAX, EDX // Str = Str2 je @@true // to exit true test eax, eax // not Str je @@false // to exit false test edx, edx // not Str2 je @@false // to exit false sub edx, eax // Str2 := Str2 - Str; mov ebx, [eax] // get Str 4 byte xor

2021-11-14 17:24:07    分类:问答    assembly   x86   sse   micro-optimization   sse4

制作一个编译 Tensorflow 二进制文件的 Dockerfile 以使用:SSE4.1、SSE4.2 和 AVX 指令(Make a Dockerfile that compiles a Tensorflow binary to use: SSE4.1, SSE4.2 and AVX instructions)

问题 那么,Docker 的一个目的是轻松部署环境来测试软件,对吗? 谁能告诉我如何编译 Tensorflow 二进制文件以使用:docker 文件上的 SSE4.1、SSE4.2? 任何人都可以指出我这样做的 docker 文件吗? 如果有可能吗? 总结一下,两个问题: 是否可以使用编译 Tensorflow 二进制文件的 docker 文件:SSE4.1、SSE4.2(和 GPU,我只找到了一个) 你能告诉我在哪里可以找到一个 docker 文件或者一个很好的教程吗? “这个问题的目的是避免以下情况:主机设置工作但 docker 设置不起作用,因为 Tensorflow 没有以特定方式编译。” 就像下图一样。 回答1 可以用作起点的此类 Dockerfile 的工作示例位于:https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/docker(有关详细信息,请参阅README.md )。 更准确地说,它是一组参数化的 Docker 文件,构建以parameterized_docker_build.sh开始。 在 Docker 中成功编译 TensorFlow 的命令示例是: export TF_DOCKER_BUILD_IS_DEVEL=YES export TF_DOCKER_BUILD

2021-10-21 10:06:09    分类:技术分享    docker   tensorflow   cpu   sse4

为多个 SIMD 架构生成代码(Generate code for multiple SIMD architectures)

问题 我编写了一个库,在其中使用 CMake 验证 MMX、SSE、SSE2、SSE4、AVX、AVX2 和 AVX-512 标头是否存在。 除此之外,我检查指令是否存在,如果存在,我添加必要的编译器标志,-msse2 -mavx -mfma 等。 这一切都非常好,但我想部署一个单一的二进制文件,它适用于一系列处理器。 问题:是否可以告诉编译器 (GCC),无论何时使用 SIMD 优化函数,它都必须为体系结构列表生成代码? 当然还有引入高级分支 我在想类似于编译器如何为函数生成代码,其中输入指针是 4 或 8 字节对齐的。 为了防止这种情况,我使用了__builtin_assume_aligned宏。 什么是最佳实践? 多个二进制文件? 命名? 回答1 只要你不关心便携性,是的。 通过使用 target_clone 函数属性,最近版本的 GCC 使这比我所知道的任何其他编译器更容易。 只需添加属性,以及要为其创建版本的目标列表,GCC 将自动创建不同的变体,以及在运行时自动选择版本的调度函数。 如果你想要更多的可移植性,你可以使用 target 属性,clang 和 icc 也支持,但你必须自己编写调度函数(这并不困难),并多次发出该函数(通常使用宏,或重复包含标题)。 AFAIK,如果您希望您的代码与 MSVC 一起使用,您将需要多个具有不同选项的编译器调用。 回答2

2021-10-15 17:34:52    分类:技术分享    gcc   simd   avx   sse4

是否可以使用 PTEST 来测试两个寄存器是否都为零或其他条件?(Can PTEST be used to test if two registers are both zero or some other condition?)

问题 除了测试单个寄存器是否全为零之外,您还可以使用 SSE4.1 ptest 做什么? 您能否结合使用 SF 和 CF 来测试有关两个未知输入寄存器的任何有用信息? PTEST 有什么用? 您会认为检查打包比较的结果(如 PCMPEQD 或 CMPPS)会很好,但至少在 Intel CPU 上,使用 PTEST + JCC 进行比较和分支比使用 PMOVMSK(B /PS/PD) + 宏融合 CMP+JCC。 另请参见检查两个 SSE 寄存器是否都为零而不销毁它们 回答1 不,除非我遗漏了一些聪明的东西,否则带有两个未知寄存器的ptest通常对于检查有关它们的某些属性没有用处。 (除了明显的东西,你已经想要一个按位与,比如两个位图之间的交集)。 测试两个寄存器是否全为零,或将它们放在一起,然后对自身进行 PTEST。 ptest xmm0, xmm1产生两个结果: ZF = xmm0 & xmm1全零吗? CF = 是(~xmm0) & xmm1全零? 如果第二个向量全为零,则标志完全不依赖于第一个向量中的位。 将“全零”检查视为 AND 和 ANDNOT 结果的NOT(bitwise horizontal-OR())很有用。 但可能不会,因为这对我的大脑来说太多了,无法轻松思考。 垂直与然后水平或的序列确实可能使您更容易理解为什么 PTEST

2021-10-15 04:25:24    分类:技术分享    assembly   x86   sse   intrinsics   sse4

使用 sse 的快速紧凑寄存器(fast compact register using sse)

问题 我想弄清楚如何使用 sse _mm_shuffle_epi8 来压缩 128 位寄存器。 假设我有一个输入变量 __m128i target 基本上是 8 个 16 位,表示为: a[0], a[1] ... a[7]. // each slot is 16 bits 我的输出被称为: __m128i output 现在我有一个大小为 8 的位向量: char bit_mask // 8 bits, i-th bit each indicate if // the corresponding a[i] should be included 好的,我怎样才能根据bit_mask和输入目标得到最终结果呢? 假设我的位向量是: [0 1 1 0 0 0 0 0] 那么我想要的结果是: output = [a1, a2 , ... ] 使用 _mm_shuffle_epi8 执行此操作的任何已知方法? 假设我使用查找数组:_mm_shuffle_epi8(a, mask_lookup[bitvector]); 如何创建数组? 回答1 简单且非常快,但需要 4KB 的表空间: _mm_shuffle_epi8(a, mask_lookup[bitvector]); 您只需将所有 256 个可能的洗牌掩码存储在由位向量索引的表中。

2021-10-14 12:34:35    分类:技术分享    c++   sse   sse4