对于那些致力于程序优化和性能调整的人来说,一个普遍的问题是,您如何确定您的代码是受 CPU 限制还是受内存限制?我总体上理解这些概念,但是如果我说“y”的负载和存储量以及“2y”的计算量,人们如何找到瓶颈?
您还可以弄清楚您将大部分时间花在哪里,并说,如果您在每次循环迭代中将“x”数量的数据加载到缓存中(如果它的内存受限),那么您的代码会运行得更快吗?除了反复试验,还有什么精确的方法可以确定这个“x”吗?
是否有任何工具可以使用,比如 IA-32 或 IA-64 架构?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' 向量加载到内存中,但这也没有帮助。
假设它的内存受限,我已经完成了所有这些,但我想确定。有办法吗?