覆盆子Pi 1和2中ARM11和Cortex-A7核心的每个周期的峰值浮点数

覆盆子Pi 1和2中ARM11和Cortex-A7核心的每个周期的峰值浮点数,arm,raspberry-pi,cpu-architecture,Arm,Raspberry Pi,Cpu Architecture,我想知道Raspberry Pi 1中ARM1176JZF-S内核和Raspberry Pi 2中Cortex-A7内核的每个周期的峰值触发器 从外观上看,VFPv2似乎可以每一个时钟周期执行一个SP MAC,每隔一个时钟周期执行一个DP MAC。此外,还有三条可以并行运行的管道:MAC管道(FMAC)、分区和sqrt管道(DS)以及加载/存储管道(LS)。基于此,Raspberry PI 1的ARM1176JZF-S似乎至少可以做到(从FMAC管道) 1 DP触发器/周期:一个MAC/2周

我想知道Raspberry Pi 1中ARM1176JZF-S内核和Raspberry Pi 2中Cortex-A7内核的每个周期的峰值触发器


从外观上看,VFPv2似乎可以每一个时钟周期执行一个SP MAC,每隔一个时钟周期执行一个DP MAC。此外,还有三条可以并行运行的管道:MAC管道(FMAC)、分区和sqrt管道(DS)以及加载/存储管道(LS)。基于此,Raspberry PI 1的ARM1176JZF-S似乎至少可以做到(从FMAC管道)

  • 1 DP触发器/周期:一个MAC/2周期
  • 2个SP触发器/周期:一个MAC/周期
声称覆盆子皮1的失败是。除以0.700 GHz,得出小于0.06 DP触发器/周期。这比我估计的1 DP FLOP/周期大约少17倍

那么正确的答案是什么


对于覆盆子Pi 2中的Cortex-A7处理器,我相信它与Cortex-A9是一样的。是:

  • 1.5 DP触发器/周期:每隔一个周期标量加法+标量乘法
  • 4个SP触发器/周期:每隔一个周期4宽霓虹灯加法+每隔一个周期4宽霓虹灯乘法
覆盆子Pi 2的触发器/循环/核心与Corrtex-A9相同吗?如果不是,正确答案是什么

编辑:

(当涉及峰值触发器/周期时)为:

  • Cortex-A9是双发指令(每个时钟两条指令),Cortex-A7是“A7不能双发浮点或霓虹灯指令”
  • Cortex-A9是一个无序(OoO)处理器,Cortex-A7不是
我不确定OoO为什么会影响峰值失败。双重问题当然应该得到解决。我认为这将把峰值失败减少一半

编辑:根据Stephen Canon在评论中给出的表格,这里是我对Cortex-A7的新峰值翻牌

  • 0.5 DP触发器/周期:每四个周期一次VMLA.F64(VFP)
  • 1.0 DP触发器/周期:每个周期一个VADD.F64(VFP)
  • 2.0 SP触发器/周期:每个周期一个VMLA.F32(VFP)
  • 2.0 SP触发器/周期:每隔一个周期,两个32位浮点上的一个VMLA.F32(霓虹灯)

示例1编译代码MP MFLOPSPiNeon,在900 MHz Rpi2上获得>647 MFLOPS(数据字3.2k至3.2M)。没有螺纹,拆卸似乎是一样的。每个数据字使用的编译/链接命令和32个操作的C代码如下[有人可能会建议更快的编译选项]

   MP-MFLOPS Compiled NEON v1.0

   gcc mpmflops.c cpuidc.c -lrt -lc -lm -O3 -mcpu=cortex-a7
    -mfloat-abi=hard -mfpu=neon-vfpv4 -funsafe-math-optimizations -lpthread -o MP-MFLOPSPiNeon

   32 OPs/Word 1 CPU 692 MFLOPS

 void triadplus2(int n, float a, float b, float c, float d,
                 float e, float f, float g, float h, float j,
                 float k, float l, float m, float o, float p,
                 float q, float r, float s, float t, float u,
                 float v, float w, float y, float *x)
 {
     int i;
     for(i=0; i<n; i++)
     x[i] = (x[i]+a)*b-(x[i]+c)*d+(x[i]+e)*f-(x[i]+g)*h+(x[i]+j)*k
     -(x[i]+l)*m+(x[i]+o)*p-(x[i]+q)*r+(x[i]+s)*t-(x[i]+u)*v+(x[i]+w)*y;
 }
示例2-使用NEON内在函数(在我知道融合指令之前)>700 mFLOP。第一个C代码:

 32 Operations per word
 C NEON Intrinsics 
 n = words 3.2k, 32k, 3.2M
 similar results > 700 MFLOPS.

 for(i=0; i<n; i=i+4)
 {
     x41 = vld1q_f32(ptrx1);

     z41 = vaddq_f32(x41, a41);
     z41 = vmulq_f32(z41, b41);

     z42 = vaddq_f32(x41, c41);
     z42 = vmulq_f32(z42, d41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, e41);
     z42 = vmulq_f32(z42, f41);
     z41 = vaddq_f32(z41, z42);

     z42 = vaddq_f32(x41, g41);
     z42 = vmulq_f32(z42, h41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, j41);
     z42 = vmulq_f32(z42, k41);
     z41 = vaddq_f32(z41, z42);

     z42 = vaddq_f32(x41, l41);
     z42 = vmulq_f32(z42, m41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, o41);
     z42 = vmulq_f32(z42, p41);
     z41 = vaddq_f32(z41, z42);

     z42 = vaddq_f32(x41, q41);
     z42 = vmulq_f32(z42, r41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, s41);
     z42 = vmulq_f32(z42, t41);
     z41 = vaddq_f32(z41, z42);

     z42 = vaddq_f32(x41, u41);
     z42 = vmulq_f32(z42, v41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, w41);
     z42 = vmulq_f32(z42, y41);
     z41 = vaddq_f32(z41, z42);

     vst1q_f32(ptrx1, z41);

     ptrx1 = ptrx1 + 4;
 }

我知道计算机上的整数SIMD计算。我对这个问题不感兴趣。我只对ARM11和Cortex-A7内核的失败感兴趣。糟糕的是,不知何故,我误读了,错误地看待了差异。基准测试是主观的,唯一重要的是你最喜欢(或至少可以容忍)的编译器,以及你计划部署的代码和运行速度。除非这是出于营销或广告的原因,否则就从武器营销人员那里重复一遍。700 MHz RPi的41 DP MFLOP可能基于Linpack基准。我的版本在900 MHz RPi 2上获得相同的额定值和147 MFLOPS。我最快的SP MFLOPS测试,每个读/写的数据字有32个乘法或加法操作,在RPi上达到192个MFLOPS,RPi 2为410,然后通过NEON(1581 4个核)达到709。Cortex-A7 FPU绝对不同于Cortex-A9。我不知道ARM有任何公开的计时文档,但快速搜索确实会找到有人编译的计时特征表:为了回答OP的问题,同时执行的浮点操作的峰值在哪里和什么地方?问题是每个周期有4次触发器,所以如果有时同时发生4次触发器,并且在一个周期内完成,答案是“4”。@wallyk,如果说每个周期有4次触发器,那么它需要吞吐量限制,而不是延迟限制。我的意思是,让我们假设一个64位wite(两个浮点数)MAC Neon指令的延迟为4,但吞吐量为1,那么这将要求这些指令中的四条可以在四个时钟周期内发生,以要求4次触发器/周期。一条指令是不够的。
 32 Operations per word
 C NEON Intrinsics 
 n = words 3.2k, 32k, 3.2M
 similar results > 700 MFLOPS.

 for(i=0; i<n; i=i+4)
 {
     x41 = vld1q_f32(ptrx1);

     z41 = vaddq_f32(x41, a41);
     z41 = vmulq_f32(z41, b41);

     z42 = vaddq_f32(x41, c41);
     z42 = vmulq_f32(z42, d41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, e41);
     z42 = vmulq_f32(z42, f41);
     z41 = vaddq_f32(z41, z42);

     z42 = vaddq_f32(x41, g41);
     z42 = vmulq_f32(z42, h41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, j41);
     z42 = vmulq_f32(z42, k41);
     z41 = vaddq_f32(z41, z42);

     z42 = vaddq_f32(x41, l41);
     z42 = vmulq_f32(z42, m41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, o41);
     z42 = vmulq_f32(z42, p41);
     z41 = vaddq_f32(z41, z42);

     z42 = vaddq_f32(x41, q41);
     z42 = vmulq_f32(z42, r41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, s41);
     z42 = vmulq_f32(z42, t41);
     z41 = vaddq_f32(z41, z42);

     z42 = vaddq_f32(x41, u41);
     z42 = vmulq_f32(z42, v41);
     z41 = vsubq_f32(z41, z42);

     z42 = vaddq_f32(x41, w41);
     z42 = vmulq_f32(z42, y41);
     z41 = vaddq_f32(z41, z42);

     vst1q_f32(ptrx1, z41);

     ptrx1 = ptrx1 + 4;
 }
Assembly Code

.L26:
    vld1.32 {d16-d17}, [ip]
    vld1.64 {d20-d21}, [sp:64]
    vadd.f32        q9, q8, q14
    vadd.f32        q11, q8, q10
    vldr    d24, [sp, #16]
    vldr    d25, [sp, #24]
    vmul.f32        q11, q11, q13
    vmul.f32        q9, q9, q12
    vldr    d24, [sp, #32]
    vldr    d25, [sp, #40]
    vsub.f32        q11, q11, q9
    vadd.f32        q10, q8, q12
    vldr    d18, [sp, #48]
    vldr    d19, [sp, #56]
    vldr    d24, [sp, #64]
    vldr    d25, [sp, #72]
    vmul.f32        q10, q10, q9
    vadd.f32        q9, q8, q12
    vadd.f32        q11, q11, q10
    vldr    d20, [sp, #80]
    vldr    d21, [sp, #88]
    vldr    d24, [sp, #96]
    vldr    d25, [sp, #104]
    vmul.f32        q9, q9, q10
    vadd.f32        q10, q8, q12
    vsub.f32        q11, q11, q9
    vldr    d18, [sp, #112]
    vldr    d19, [sp, #120]
    vldr    d24, [sp, #128]
    vldr    d25, [sp, #136]
    vmul.f32        q10, q10, q9
    vadd.f32        q9, q8, q12
    vadd.f32        q11, q11, q10
    vldr    d24, [sp, #160]
    vldr    d25, [sp, #168]
    vldr    d20, [sp, #144]
    vldr    d21, [sp, #152]
    add     r3, r3, #4
    cmp     r0, r3
    vmul.f32        q9, q9, q10
    vadd.f32        q10, q8, q12
    vsub.f32        q11, q11, q9
    vmul.f32        q10, q10, q15
    vadd.f32        q9, q8, q3
    vadd.f32        q11, q11, q10
    vmul.f32        q9, q9, q2
    vadd.f32        q10, q8, q1
    vsub.f32        q11, q11, q9
    vmul.f32        q10, q10, q0
    vadd.f32        q9, q8, q4
    vadd.f32        q10, q11, q10
    vmul.f32        q9, q9, q5
    vadd.f32        q8, q8, q6
    vsub.f32        q10, q10, q9
    vmul.f32        q8, q8, q7
    vadd.f32        q10, q10, q8
    vst1.32 {d20-d21}, [ip]!
    bgt     .L26