当前位置: 首页 > news >正文

X265性能分析开源代码

X265性能分析开源代码

    • 性能测试函数解析
  • 对应的宏函数解析展开
    • 1.为什么基准的性能测试次数是优化版本的1/4
    • 2.为什么清除异常值,怎么清除异常值的?
    • 3.周期数到底是怎么去计算的?

性能测试函数解析

void IntraPredHarness::measureSpeed(const EncoderPrimitives& ref, const EncoderPrimitives& opt)
{int width = 64;                     // 默认测试宽度uint16_t srcStride = 96;            // 参考像素缓冲区步长(含填充区域)// 遍历所有块大小:4x4(0)到32x32(3)for (int i = BLOCK_4x4; i <= BLOCK_32x32; i++) {const int size = (1 << (i + 2)); // 计算实际尺寸:4<<i → 4/8/16/32/* --- 测试Planar模式 --- */if (opt.cu[i].intra_pred[PLANAR_IDX])  // 如果优化代码实现了Planar模式{printf("intra_planar_%dx%d", size, size);// 调用REPORT_SPEEDUP比较优化和参考实现REPORT_SPEEDUP(opt.cu[i].intra_pred[PLANAR_IDX], ref.cu[i].intra_pred[PLANAR_IDX],pixel_out_vec,       // 输出缓冲区FENC_STRIDE,         // 输出步长pixel_buff + srcStride, // 参考像素(跳过填充)0, 0);               // 模式号和滤波标志}/* --- 测试DC模式 --- */if (opt.cu[i].intra_pred[DC_IDX]) {// 不过滤的情况printf("intra_dc_%dx%d[f=0]", size, size);REPORT_SPEEDUP(opt.cu[i].intra_pred[DC_IDX], ref.cu[i].intra_pred[DC_IDX],pixel_out_vec, FENC_STRIDE, pixel_buff + srcStride, 0, 0);// 仅对小块(≤16x16)测试滤波情况if (size <= 16) {printf("intra_dc_%dx%d[f=1]", size, size);REPORT_SPEEDUP(opt.cu[i].intra_pred[DC_IDX], ref.cu[i].intra_pred[DC_IDX],pixel_out_vec, FENC_STRIDE, pixel_buff + srcStride, 0, 1); // 滤波标志=1}}/* --- 测试AllAngs模式(组合角度预测)--- */if (opt.cu[i].intra_pred_allangs) {bool bFilter = (size <= 16);  // 小块启用滤波pixel* refAbove = pixel_buff + srcStride;  // 上方参考像素pixel* refLeft = refAbove + 3 * size;      // 左侧参考像素refLeft[0] = refAbove[0];                  // 填充左上角像素printf("intra_allangs%dx%d", size, size);REPORT_SPEEDUP(opt.cu[i].intra_pred_allangs,ref.cu[i].intra_pred_allangs,pixel_out_33_vec,  // 输出缓冲区(33种角度)refAbove, refLeft, // 参考像素指针bFilter);          // 滤波标志}/* --- 测试所有角度模式(2-34) --- */for (int mode = 2; mode <= 34; mode++) {if (opt.cu[i].intra_pred[mode])  // 如果实现了该角度模式{width = 1 << (i + 2);        // 重新计算块宽bool bFilter = (width <= 16); // 滤波标志pixel* refAbove = pixel_buff + srcStride;pixel* refLeft = refAbove + 3 * width;refLeft[0] = refAbove[0];    // 填充左上角printf("intra_ang_%dx%d[%2d]", width, width, mode);REPORT_SPEEDUP(opt.cu[i].intra_pred[mode],ref.cu[i].intra_pred[mode],pixel_out_vec, FENC_STRIDE,pixel_buff + srcStride,mode,          // 当前角度模式号bFilter);      // 滤波标志}}/* --- 测试帧内滤波 --- */if (opt.cu[i].intra_filter) {printf("intra_filter_%dx%d", size, size);REPORT_SPEEDUP(opt.cu[i].intra_filter,ref.cu[i].intra_filter,pixel_buff,        // 输入缓冲区pixel_out_c);      // 输出缓冲区}}
}

对应的宏函数解析展开

#define BENCH_RUNS 2000/* Adapted from checkasm.c, runs each optimized primitive four times, measures rdtsc* and discards invalid times. Repeats BENCH_RUNS times to get a good average.* Then measures the C reference with BENCH_RUNS / 4 runs and reports X factor and average cycles.*/
#define REPORT_SPEEDUP(RUNOPT, RUNREF, ...) \{ \uint32_t cycles = 0; int runs = 0; \RUNOPT(__VA_ARGS__); \ //预热运行,避免冷启动影响for (int ti = 0; ti < BENCH_RUNS; ti++) { \ /* 主测试循环:运行BENCH_RUNS次,每次测4次连续调用 */uint32_t t0 = (uint32_t)__rdtsc(); \RUNOPT(__VA_ARGS__); \RUNOPT(__VA_ARGS__); \RUNOPT(__VA_ARGS__); \RUNOPT(__VA_ARGS__); \uint32_t t1 = (uint32_t)__rdtsc() - t0; \// 计算周期数if (t1 * runs <= cycles * 4 && ti > 0) { cycles += t1; runs++; } V\   /* 过滤异常值(超过平均4倍的测量值) */ \} \/* --- 测量参考代码性能(减少迭代次数)--- */ uint32_t refcycles = 0; int refruns = 0; \RUNREF(__VA_ARGS__); \for (int ti = 0; ti < BENCH_RUNS / 4; ti++) { \uint32_t t0 = (uint32_t)__rdtsc(); \RUNREF(__VA_ARGS__); \RUNREF(__VA_ARGS__); \RUNREF(__VA_ARGS__); \RUNREF(__VA_ARGS__); \uint32_t t1 = (uint32_t)__rdtsc() - t0; \if (t1 * refruns <= refcycles * 4 && ti > 0) { refcycles += t1; refruns++; } \} \ /* --- 计算结果 --- */x265_emms(); \  // 清空MMX/SSE状态(避免浮点寄存器污染)float optperf = (10.0f * cycles / runs) / 4; \  /* 计算平均每次调用的周期数(×10提高显示精度) */float refperf = (10.0f * refcycles / refruns) / 4; \printf(" | \t%3.2fx | ", refperf / optperf); \  /* 输出加速比和绝对周期数 */ printf("\t %-8.2lf | \t %-8.2lf\n", optperf, refperf); \}
}

1.为什么基准的性能测试次数是优化版本的1/4

这里​​参考代码(RUNREF)的测试次数是 BENCH_RUNS / 4​​,而优化代码(RUNOPT)的测试次数是完整的 BENCH_RUNS
猜测有几个原因
参考代码(RUNREF)​​:只需提供基准参考值,不需要和优化代码相同的精度,因此减少测试次数,​优化代码(RUNOPT)​需要更精确的测量。

2.为什么清除异常值,怎么清除异常值的?

总结:首轮除外,每次更新接受小于平均值的数值值

if (t1 * runs <= cycles * 4 && ti > 0) { cycles += t1; runs++; 
}

​​变量含义​​:
t1:当前测量的4次调用总周期数
runs:已接受的有效测量次数
cycles:已累积的总周期数
ti:当前迭代索引(从0开始)
​​逻辑分解​​:
t1 * runs:当前测量值 × 历史有效次数
cycles * 4:历史总周期数 × 4
ti > 0:跳过第一次测量(避免除零风险)
实际效果:
在这里插入图片描述
实际演算:
在这里插入图片描述

3.周期数到底是怎么去计算的?

/* fallback for older GCC/MinGW */
static inline uint32_t __rdtsc(void)
{uint32_t a = 0;#if X265_ARCH_X86asm volatile("rdtsc" : "=a" (a) ::"edx");
#elif X265_ARCH_ARM// TOD-DO: verify following inline asm to get cpu Timestamp Counter for ARM arch// asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(a));// TO-DO: replace clock() function with appropriate ARM cpu instructionsa = clock();
#elif  X265_ARCH_ARM64asm volatile("isb" : : : "memory");asm volatile("mrs %0, cntvct_el0" : "=r"(a));
#endifreturn a;
}

咱们这里只对armv8架构的进行解读

asm volatile("isb" : : : "memory");
asm volatile("mrs %0, cntvct_el0" : "=r"(a));
  • ​​指令​​:
    isb:指令同步屏障(确保指令顺序执行)
    mrs %0, cntvct_el0:读取虚拟计数器值
  • 寄存器​​:
    cntvct_el0:用户态可访问的64位虚拟计数器
    频率通常为1-100MHz(非实际CPU频率)
http://www.lryc.cn/news/615987.html

相关文章:

  • 【高等数学】第八章 向量代数与空间解析几何——第六节 空间曲线及其方程
  • Video Lecture 8 Page Fault
  • 使用 Python 进行图片识别的项目开发
  • git merge和git rebase的区别
  • MIRO中文本如何传入FI凭证的
  • 基于Spring SSE构建实时监控系统
  • SpringCloud详细笔记
  • es-drager-blog
  • Java 日常开发笔记(小程序页面交互传参-id)
  • 震动马达实现库函数版(STC8)
  • 升级 JDK 17 碰到的请求 https 问题
  • 如何在Python中使用flask框架搭建web服务?
  • org.apache.hadoop.hbase.TableNotFoundException: ApplicationIndex
  • C/C++类型转换(C++四大强制类型转换)
  • 6.3 完成 RAG
  • TSF应用开发与运维部署
  • 下载UOS桌面专业版系统镜像
  • 强制类型转换
  • [TryHackMe]OverPass2(流量包分析+sha256+suid提权)
  • 【Vue✨】Vue3 中英文切换功能实现
  • 计算机网络:如何理解目的网络不再是一个完整的分类网络
  • RAG技术与应用
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘optuna’问题
  • Linux环境下实现简单TCP通信(c)
  • TypeScript 中的as const是什么?
  • Shell脚本-变量的分类
  • 从零到精通:嵌入式BLE开发实战指南
  • Spring Boot 全局异常处理与日志监控实战
  • go加速配置(下载第三方库)
  • 元数据管理与数据治理平台:Apache Atlas 通知和业务元数据 Notifications And Business Metadata