c - 了解代码示例是受 CPU 限制还是受内存限制

标签 c performance optimization sse

作为对那些从事程序优化和性能调整工作的人的一个普遍问题,您如何确定您的代码是受 CPU 限制还是内存限制?我大体上理解这些概念,但如果我说“y”个加载和存储量以及“2y”个计算,那么如何找到瓶颈?

您还可以弄清楚您究竟将大部分时间花在哪里,并且说,如果您在每次循环迭代中将“x”量的数据加载到缓存中(如果它的内存受限),那么您的代码会运行得更快吗?除了反复试验之外,是否有任何精确的方法来确定这个“x”?

在 IA-32 或 IA-64 架构上,您是否会使用任何工具? VTune 有帮助吗?

例如,我目前正在执行以下操作:

我有 26 个 8*8 的复数 double 矩阵,我必须对这 26 个矩阵中的每一个矩阵执行一个 MVM(矩阵 vector 乘法),其中包含 (~4000) 个长度为 8 的 vector 。我使用 SSE 执行复数乘法。

/*Copy 26 matrices to temporary storage*/
for(int i=0;i<4000;i+=2){//Loop over the 4000 vectors 
    for(int k=0;k<26;k++){//Loop over the 26 matrices
       /*
        Perform MVM in blocks of '2' between kth matrix and 
        'i' and 'i+1' vector
       */     

    }
}

这 26 个矩阵占用 26kb(L1 缓存为 32KB),我将 vector 放在内存中,这样我就有了 stride'1' 访问。一旦我对包含 27 个矩阵的 vector 执行 MVM,我就不会再访问它们,所以我认为缓存阻塞不会有帮助。我已经使用了矢量化,但我仍然停留在 60% 的峰值性能上。

我尝试将 64 个 vector 复制到临时存储中,对于外循环的每次迭代都认为它们将在缓存中并提供帮助,但它只会降低性能。我尝试按以下方式使用 _mm_prefetch():当我处理完大约一半的矩阵时,我将下一个“i”和“i+1” vector 加载到内存中,但这也没有帮助。

我已经完成了所有这些假设它的内存限制,但我想确定。有办法吗?

最佳答案

据我了解,最好的方法是分析您的应用程序/工作负载。根据输入数据,应用程序/工作负载的特性可能会有很大差异。然而,这些行为可以用极少数来量化 phases引用 [2 , 3 ] 和直方图可以大致说明要优化的工作负载的最频繁路径。您提出的问题还需要架构的基准程序 [如 SPEC2006、PARSEC、Media bench 等],并且很难笼统地回答(并且是计算机架构研究的一个活跃部分)。但是,对于特定情况,可以针对不同的内存层次结构说明定量结果。您可以使用以下工具:

  • 表现
  • 个人资料
  • VTune
  • 利维德
  • LLTng

和其他监控和模拟工具来获取应用程序的分析痕迹。您可以查看性能计数器,如 IPC、CPI(用于 CPU 绑定(bind))和内存访问、缓存未命中、缓存访问和其他内存计数器以确定内存边界。如 IPC、每周期内存访问 (MPC),通常用于确定应用程序/工作负载的内存边界。 为了专门改进矩阵乘法,我建议使用优化算法,如 LAPACK .

关于c - 了解代码示例是受 CPU 限制还是受内存限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14988481/

相关文章:

javascript - 将数据加载为 .js 文件与加载为 JSON

c - 如何仅使用printf和3个变量按升序排列整数?

c - uint32_t 64 位对齐?

performance - 加特林进纸器问题 : No attribute name 'CSVFieldName' is defined issue

java - 为什么哈希函数不使用随机性?

optimization - 如何优化2个相同的内核,占用率50%,可以在CUDA中同时运行?

php - 优化数组合并操作

MySQL 优化 - 需要建议

C 套接字 - 保留连接池以供重用 - s

c - 出现段错误。不知道为什么