相关疑难解决方法(0)

为什么我的程序在完全循环8192个元素时会变慢?

以下是相关程序的摘录.矩阵img[][]的大小为SIZE×SIZE,并在以下位置初始化:

img[j][i] = 2 * j + i

然后,你创建一个矩阵res[][],这里的每个字段都是img矩阵中它周围9个字段的平均值.为简单起见,边框保留为0.

for(i=1;i<SIZE-1;i++) 
    for(j=1;j<SIZE-1;j++) {
        res[j][i]=0;
        for(k=-1;k<2;k++) 
            for(l=-1;l<2;l++) 
                res[j][i] += img[j+l][i+k];
        res[j][i] /= 9;
}
Run Code Online (Sandbox Code Playgroud)

这就是该计划的全部内容.为了完整起见,以下是之前的内容.没有代码.如您所见,它只是初始化.

#define SIZE 8192
float img[SIZE][SIZE]; // input image
float res[SIZE][SIZE]; //result of mean filter
int i,j,k,l;
for(i=0;i<SIZE;i++) 
    for(j=0;j<SIZE;j++) 
        img[j][i] = (2*j+i)%8196;
Run Code Online (Sandbox Code Playgroud)

基本上,当SIZE是2048的倍数时,此程序很慢,例如执行时间:

SIZE = 8191: 3.44 secs
SIZE = 8192: 7.20 secs
SIZE = 8193: 3.18 secs
Run Code Online (Sandbox Code Playgroud)

编译器是GCC.据我所知,这是因为内存管理,但我对这个主题并不太了解,这就是我在这里问的原因.

另外如何解决这个问题会很好,但如果有人能够解释这些执行时间,我已经足够开心了.

我已经知道malloc/free了,但问题不在于使用的内存量,它只是执行时间,所以我不知道这会有多大帮助.

c++ performance gcc memory-management

745
推荐指数
2
解决办法
9万
查看次数

在迭代2D数组时,为什么循环的顺序会影响性能?

可能重复:
这两个for循环中的哪一个在时间和缓存性能方面更有效

下面是两个几乎相同的程序,除了我切换ij变量.它们都运行在不同的时间.有人能解释为什么会这样吗?

版本1

#include <stdio.h>
#include <stdlib.h>

main () {
  int i,j;
  static int x[4000][4000];
  for (i = 0; i < 4000; i++) {
    for (j = 0; j < 4000; j++) {
      x[j][i] = i + j; }
  }
}
Run Code Online (Sandbox Code Playgroud)

版本2

#include <stdio.h>
#include <stdlib.h>

main () {
  int i,j;
  static int x[4000][4000];
  for (j = 0; j < 4000; j++) {
     for (i = 0; i < 4000; i++) {
       x[j][i] = i …
Run Code Online (Sandbox Code Playgroud)

c optimization performance for-loop cpu-cache

350
推荐指数
6
解决办法
4万
查看次数

为什么转换512x512的矩阵要比转换513x513的矩阵慢得多?

在对不同尺寸的方形矩阵进行一些实验后,出现了一种模式.转换一个大小的矩阵2^n2^n+1总是比转换一个大小的矩阵.对于较小的值n,差异并不重要.

然而,在512的值上会出现很大的差异.(至少对我而言)

免责声明:我知道由于元素的双重交换,函数实际上并没有转置矩阵,但它没有任何区别.

遵循代码:

#define SAMPLES 1000
#define MATSIZE 512

#include <time.h>
#include <iostream>
int mat[MATSIZE][MATSIZE];

void transpose()
{
   for ( int i = 0 ; i < MATSIZE ; i++ )
   for ( int j = 0 ; j < MATSIZE ; j++ )
   {
       int aux = mat[i][j];
       mat[i][j] = mat[j][i];
       mat[j][i] = aux;
   }
}

int main()
{
   //initialize matrix
   for ( int i = 0 ; …
Run Code Online (Sandbox Code Playgroud)

c++ optimization performance

208
推荐指数
3
解决办法
3万
查看次数

访问各种缓存和主内存的近似成本?

任何人都可以给我大概的时间(以纳秒为单位)来访问L1,L2和L3缓存,以及Intel i7处理器上的主内存吗?

虽然这不是一个特别的编程问题,但是对于某些低延迟编程挑战而言,了解这些速度细节是必要的.

memory latency low-latency cpu-cache

167
推荐指数
5
解决办法
8万
查看次数

缓存线如何工作?

据我所知,处理器通过缓存线将数据带入缓存,例如,在我的Atom处理器上,无论读取的实际数据大小如何,一次都会带来大约64个字节.

我的问题是:

想象一下,你需要从内存中读取一个字节,这64个字节将被带入缓存?

我可以看到的两种可能性是,64字节从感兴趣的字节下方最接近的64字节边界开始,或者64字节以某种预定方式在字节周围扩展(例如,一半以下,一半以上,或者上述所有).

这是什么?

memory caching processor line

152
推荐指数
4
解决办法
7万
查看次数

为什么2048x2048与2047x2047阵列乘法相比会有巨大的性能损失?

我正在进行一些矩阵乘法基准测试,如前面提到的 为什么MATLAB在矩阵乘法中如此之快?

现在我有另一个问题,当乘以两个2048x2048矩阵时,C#和其他矩阵之间存在很大差异.当我尝试只乘2047x2047矩阵时,看起来很正常.还添加了一些其他的比较.

1024x1024 - 10秒.

1027x1027 - 10秒.

2047x2047 - 90秒.

2048x2048 - 300秒.

2049x2049 - 91秒.(更新)

2500x2500 - 166秒

对于2k×2k的情况,这是三分半钟的差异.

使用2dim数组

//Array init like this
int rozmer = 2048;
float[,] matice = new float[rozmer, rozmer];

//Main multiply code
for(int j = 0; j < rozmer; j++)
{
   for (int k = 0; k < rozmer; k++)
   {
     float temp = 0;
     for (int m = 0; m < rozmer; m++)
     {
       temp = temp + matice1[j,m] * matice2[m,k]; …
Run Code Online (Sandbox Code Playgroud)

c# arrays matrix-multiplication

127
推荐指数
5
解决办法
6473
查看次数

矩阵乘法:矩阵大小差异小,时序差异大

我有一个矩阵乘法代码,如下所示:

for(i = 0; i < dimension; i++)
    for(j = 0; j < dimension; j++)
        for(k = 0; k < dimension; k++)
            C[dimension*i+j] += A[dimension*i+k] * B[dimension*k+j];
Run Code Online (Sandbox Code Playgroud)

这里,矩阵的大小由表示dimension.现在,如果矩阵的大小是2000,运行这段代码需要147秒,而如果矩阵的大小是2048,则需要447秒.所以虽然差别没有.乘法是(2048*2048*2048)/(2000*2000*2000)= 1.073,时间上的差异是447/147 = 3.有人可以解释为什么会发生这种情况吗?我预计它会线性扩展,但这不会发生.我不是要尝试制作最快的矩阵乘法代码,只是试图理解它为什么会发生.

规格:AMD Opteron双核节点(2.2GHz),2G RAM,gcc v 4.5.0

程序编译为 gcc -O3 simple.c

我也在英特尔的icc编译器上运行了这个,并看到了类似的结果.

编辑:

正如评论/答案中所建议的那样,我运行了维度= 2060的代码,需要145秒.

继承完整的计划:

#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>

/* change dimension size as needed */
const int dimension = 2048;
struct timeval tv; 

double timestamp()
{
        double t;
        gettimeofday(&tv, NULL);
        t = tv.tv_sec + (tv.tv_usec/1000000.0); …
Run Code Online (Sandbox Code Playgroud)

c algorithm performance matrix-multiplication

74
推荐指数
5
解决办法
1万
查看次数

CUDA矩阵加法计时,按行与 按列

我目前正在学习CUDA,正在进行一些练习.其中之一是实现以3种不同方式添加矩阵的内核:每个元素1个线程,每行1个线程,每列1个线程.矩阵是方形的,并且实现为1D向量,我只需将其索引

A[N*row + col]
Run Code Online (Sandbox Code Playgroud)

直觉上,我预计第一个选项由于线程开销而变得最慢,第二个选项是单个线程处理相邻数据以来最快的选项.

在CPU上,使用8000 x 8000的密集矩阵,我得到:

Adding on CPU - Adding down columns
Compute Time Taken: 2.21e+00 s
Adding on CPU - Adding across rows
Compute Time Taken: 2.52e-01 s
Run Code Online (Sandbox Code Playgroud)

因此,由于更多的缓存命中,所以大约加速了一个数量级.在具有相同矩阵的GPU上,我得到:

Adding one element per thread 
Compute Time Taken: 7.42e-05 s
Adding one row per thread 
Compute Time Taken: 2.52e-05 s
Adding one column per thread 
Compute Time Taken: 1.57e-05 s
Run Code Online (Sandbox Code Playgroud)

这对我来说不直观.对于最后一种情况,30-40%的加速度在大约1000×1000矩阵之上是一致的.请注意,这些时序仅是内核执行,不包括主机和设备之间的数据传输.下面是我的两个内核进行比较.

__global__
void matAddKernel2(float* A, float* B, float* C, int N)
{
        int row = threadIdx.x + …
Run Code Online (Sandbox Code Playgroud)

performance cuda

3
推荐指数
1
解决办法
1262
查看次数

嵌套循环的顺序是否对速度有影响

假设我有两个数组arrayOne并且arrayTwo在哪里arrayOne.length != arrayTwo.length(假设两个List具有不同的类似情况size()).以下任何一种都提供了速度优势吗?

java arrays performance loops nested-loops

1
推荐指数
1
解决办法
968
查看次数