以下是相关程序的摘录.矩阵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了,但问题不在于使用的内存量,它只是执行时间,所以我不知道这会有多大帮助.
下面是两个几乎相同的程序,除了我切换i和j变量.它们都运行在不同的时间.有人能解释为什么会这样吗?
版本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) 在对不同尺寸的方形矩阵进行一些实验后,出现了一种模式.转换一个大小的矩阵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) 任何人都可以给我大概的时间(以纳秒为单位)来访问L1,L2和L3缓存,以及Intel i7处理器上的主内存吗?
虽然这不是一个特别的编程问题,但是对于某些低延迟编程挑战而言,了解这些速度细节是必要的.
据我所知,处理器通过缓存线将数据带入缓存,例如,在我的Atom处理器上,无论读取的实际数据大小如何,一次都会带来大约64个字节.
我的问题是:
想象一下,你需要从内存中读取一个字节,这64个字节将被带入缓存?
我可以看到的两种可能性是,64字节从感兴趣的字节下方最接近的64字节边界开始,或者64字节以某种预定方式在字节周围扩展(例如,一半以下,一半以上,或者上述所有).
这是什么?
我正在进行一些矩阵乘法基准测试,如前面提到的 为什么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) 我有一个矩阵乘法代码,如下所示:
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) 我目前正在学习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) 假设我有两个数组arrayOne并且arrayTwo在哪里arrayOne.length != arrayTwo.length(假设两个List具有不同的类似情况size()).以下任何一种都提供了速度优势吗?
选项1
for(int i = 0 ; i < arrayOne.length ; ++i) {
for(int j = 0 ; j < arrayTwo.length ; ++j) {
//Do something
}
}
Run Code Online (Sandbox Code Playgroud)选项2
for(int i = 0 ; i < arrayTwo.length ; ++i) {
for(int j = 0 ; j < arrayOne.length ; ++j) {
//Do something
}
}
Run Code Online (Sandbox Code Playgroud)performance ×6
arrays ×2
c ×2
c++ ×2
cpu-cache ×2
memory ×2
optimization ×2
algorithm ×1
c# ×1
caching ×1
cuda ×1
for-loop ×1
gcc ×1
java ×1
latency ×1
line ×1
loops ×1
low-latency ×1
nested-loops ×1
processor ×1