作为对程序优化和性能调优工作的一般性问题,如何判断代码是CPU绑定还是内存绑定?我总体上理解这些概念,但如果我说'y'加载和存储量以及'2y'计算,那么如何找到瓶颈?
你也可以弄清楚你花在大部分时间上的确切位置并说,如果你将'x'数据量加载到缓存中(如果它的内存绑定),那么在每次循环迭代中,你的代码运行得更快?除了反复试验之外,有没有确切的方法来确定这个'x'?
您是否会使用任何工具,例如IA-32或IA-64架构? Doest VTune有帮助吗?
例如,我目前正在做以下事情:
我有26个8 * 8复数双矩阵,我必须对这26个矩阵中的每一个执行长度为8的(~4000)向量的MVM(矩阵向量乘法)。我使用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)并且我已经将向量放在内存中,这样我就可以进行stride'1'访问。一旦我在27个矩阵的向量上执行MVM,我就不再访问它们了,所以我不认为缓存阻塞会有所帮助。我使用了矢量化,但我仍然坚持60%的峰值性能。
我尝试将64个向量复制到临时存储中,因为外部循环的每次迭代都认为它们将在缓存和帮助中,但它只会降低性能。我尝试以下列方式使用_mm_prefetch():当我完成大约一半的矩阵时,我将下一个'i'和'i + 1'向量加载到内存中,但这也没有帮助。
我已经做了所有这些假设它的内存绑定但我想知道肯定。有办法吗?
答案 0 :(得分:1)
据我所知,最好的方法是分析您的应用程序/工作负载。根据输入数据,应用程序/工作负载的特性可能会发生很大变化。然而,这些行为可以用少量phases Ref [2,3来量化,并且直方图可以广泛地告知要优化的工作负载的最常见路径。你要问的问题还需要基础设施程序[如SPEC2006,PARSEC,媒体工作台等]用于架构,并且难以一般性地回答(并且是计算机架构研究的积极部分)。但是,对于特定情况,可以为不同的存储器层次结构指定定量结果。您可以使用以下工具:
和其他监视和模拟工具,以获取应用程序的分析跟踪。您可以查看性能计数器,如IPC,CPI(用于CPU绑定)和内存访问,缓存未命中,缓存访问以及其他用于确定内存有限的内存计数器。类似于IPC,每个周期的内存访问(MPC),通常用于确定应用程序/工作负载的内存限制。 为了明确改进矩阵乘法,我建议使用LAPACK中的优化算法。