相关疑难解决方法(0)

为memcpy增强了REP MOVSB

我想使用增强的REP MOVSB(ERMSB)为自定义获得高带宽memcpy.

ERMSB引入了Ivy Bridge微体系结构.如果您不知道ERMSB是什么,请参阅英特尔优化手册中的"增强型REP MOVSB和STOSB操作(ERMSB)" 部分.

我知道直接执行此操作的唯一方法是使用内联汇编.我从https://groups.google.com/forum/#!topic/gnu.gcc.help/-Bmlm_EG_fE获得了以下功能

static inline void *__movsb(void *d, const void *s, size_t n) {
  asm volatile ("rep movsb"
                : "=D" (d),
                  "=S" (s),
                  "=c" (n)
                : "0" (d),
                  "1" (s),
                  "2" (n)
                : "memory");
  return d;
}
Run Code Online (Sandbox Code Playgroud)

然而,当我使用它时,带宽远小于memcpy. 使用我的i7-6700HQ(Skylake)系统,Ubuntu 16.10,DDR4 @ 2400 MHz双通道32 GB,GCC 6.2,__movsb获得15 GB/s并memcpy获得26 GB/s.

为什么带宽如此低REP MOVSB?我该怎么做才能改善它?

这是我用来测试它的代码.

//gcc -O3 -march=native -fopenmp foo.c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly gcc memcpy

56
推荐指数
4
解决办法
1万
查看次数

为什么循环指令慢?英特尔无法有效实施吗?

LOOP(英特尔参考手动输入)递减ecx/rcx,然后如果非零则跳转.这很慢,但是英特尔不能廉价地把它变得很快吗? dec/jnz已经将宏观融合成 Sandybridge家族的一个 uop; 唯一的区别是设置标志.

loop关于各种微体系结构,来自Agner Fog的说明表:

  • K8/K10:7 m-ops
  • Bulldozer-family/Ryzen:1 m-op(与宏观融合测试和分支相同,或者jecxz)

  • P4:4次(相同jecxz)

  • P6(PII/PIII):8次
  • Pentium M,Core2:11 uops
  • Nehalem:6个uops.(11为loope/ loopne).吞吐量= 4c(loop)或7c(loope/ne).
  • SnB家族:7个uops.(11为loope/ loopne). 吞吐量=每5个循环一个,这是将循环计数器保留在内存中的瓶颈!jecxz只有2 uops,吞吐量与普通吞吐量相同jcc
  • Silvermont:7次
  • AMD Jaguar(低功耗):8 uops,5c吞吐量
  • 通过Nano3000:2 uops

难道解码器不能像lea rcx, [rcx-1]/ 那样解码jrcxz吗?这将是3 uops.至少那是没有地址大小前缀的情况,否则它必须使用ecx和截断RIP,EIP如果跳转; 也许奇怪的地址大小选择控制减量的宽度解释了许多uops?

或者更好,只需将其解码为不设置标志的融合分支和分支? dec ecx …

performance x86 assembly intel cpu-architecture

53
推荐指数
3
解决办法
6096
查看次数

标签 统计

assembly ×2

x86 ×2

c ×1

cpu-architecture ×1

gcc ×1

intel ×1

memcpy ×1

performance ×1