用c语言写一个大规模矩阵遍历的程序,在不同规模的数据下运行,比较按行遍历快还是按列遍历快。

2023-05-16

  1. 用c语言写一个大规模矩阵遍历的程序,在不同规模的数据下运行,比较按行遍历快还是按列遍历快。

1)本题老师的考察点:矩阵在计算机内存储的方式
2)解答本题时遇到的一些问题:
【1】在考虑矩阵时,考虑了数组,又想到了线性代数,刚开始还在纠结行列是不是要一致。
【2】直接从codeblocks粘贴代码过来简直太丑了,于是想到了我好久不用的csdn账号,顺便再发个原创博客。
3)代码说明:
【1】clock()函数在头文件#include<time.h>中。
【2】clock()函数的返回值类型为clock_t。
【3】clock_t是用来保存时间的数据类型,typedef long clock_t,即长整形。
【4】将MAX_ROW和MAX_COL设置成静态常量放在前面,赋值改变方便。
【5】C语言中指针分配空间用的是malloc,c++中用的是new,注意malloc分配完内存后记得free。
【6】第一次写这个题代码的时候是想着直接将矩阵每个元素的地址打印出来,后来发现打印的太多了,我真正输出的时间反而找不到了,不如只打印我的按行遍历和按列遍历的时间,方便直观。
4)代码如下:


```c
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
int main()
{
    const int MAX_ROW = 2048;
    const int MAX_COL = 2048;
    int (*a)[MAX_COL]=(int(*)[MAX_COL])malloc(sizeof(int)*MAX_ROW*MAX_COL);
    clock_t start, finish;
    //先行后列
    start = clock();
    for (int i = 0; i<MAX_ROW; i++)
    for (int j = 0; j<MAX_COL; j++)
        a[i][j] = 1;
    finish = clock();
    printf("The first travel time is %lf ms\n",(double)finish-start);
    //先列后行
    start = clock();
    for (int i = 0; i<MAX_COL; i++)
    for (int j = 0; j<MAX_ROW; j++)
        a[j][i] = 1;
    finish = clock();
    printf("The second travel time is %lf ms\n",(double)finish-start);
return 0;
}

5)运行结果:
【0】【0】行数为512,列数为512执行结果:

【0】【1】行数为512,列数为1024执行结果:
 
【0】【2】行数为512,列数为2048执行结果:
 
【0】【3】行数为512,列数为4096执行结果:
 
【0】【4】行数为512,列数为8192执行结果:
 
【0】【5】行数为512,列数为16384执行结果:
 
【1】【0】行数为1024,列数为512执行结果:
 
【1】【1】行数为1024,列数为1024执行结果:
 
【1】【2】行数为1024,列数为2048执行结果:
 
【1】【3】行数为1024,列数为4096执行结果:
 
【1】【4】行数为1024,列数为8192执行结果:
 
【1】【5】行数为1024,列数为16384执行结果:
 
【2】【0】行数为2048,列数为512执行结果:
 
【2】【1】行数为2048,列数为1024执行结果:
 
【2】【2】行数为2048,列数为2048执行结果:
 
【2】【3】行数为2048,列数为4096执行结果:
 
【2】【4】行数为2048,列数为8192执行结果:
 
【2】【5】行数为2048,列数为16384执行结果:
 
【3】【0】行数为4096,列数为512执行结果:
 
【3】【1】行数为4096,列数为1024执行结果:
 
【3】【2】行数为4096,列数为2048执行结果:
 
【3】【3】行数为4096,列数为4096执行结果:
 
【3】【4】行数为4096,列数为8192执行结果:
 
【3】【5】行数为4096,列数为16384执行结果:
 
【4】【0】行数为8192,列数为512执行结果:
 
【4】【1】行数为8192,列数为1024执行结果:
 
【4】【2】行数为8192,列数为2048执行结果:
 
【4】【3】行数为8192,列数为4096执行结果:
 
【4】【4】行数为8192,列数为8192执行结果:
 
【4】【5】行数为8192,列数为16384执行结果:
 
【5】【0】行数为16384,列数为512执行结果:
 
【5】【1】行数为16384,列数为1024执行结果:
 
【5】【2】行数为16384,列数为2048执行结果:
 
【5】【3】行数为16384,列数为4096执行结果:
 
【5】【4】行数为16384,列数为8192执行结果:
 
【5】【5】行数为16384,列数为16384执行结果:
 
6)结果处理分析:
【0】不同行列维数下对应按行遍历和按列遍历时间如下所示:(单位均为ms)
 
行\列	512	1024	2048	4096	8192	16284
512	    0\2	  1\7	 1\14	6\34	11\90	22\176
1024	1\4	  2\13 	5\34	10\83	22\179	45\365
2048	1\12	4\32	15\80	22\180	44\353	94\703
4096	5\25	11\68	23\151	43\346	93\720	193\1436
8192	11\63	21\143	43\289	88\701	185\1389	380\2854
16284	22\140	44\284	89\586	179\1399	387\2832	724\5651

【1】	分析固定行数时不同列数对应遍历时间图:
简单用matlab绘制的散点曲线图,代码如下:

```c
x=[512 1024 2048 4096 8192 16384];
y11=[0 1 1 6 11 22];
y12=[2 7 14 34 90 176];
y21=[1 2 5 10 22 45];
y22=[4 13 34 83 179 365];
y31=[1 4 15 22 44 94];
y32=[12 32 80 180 353 703];
y41=[5 11 23 43 93 193];
y42=[25 68 151 346 720 1436];
y51=[11 21 43 88 185 380];
y52=[63 143 289 701 1389 2854];
y61=[22 44 89 179 387 724];
y62=[140 284 586 1399 2832 5651];
 plot(x,y11,x,y12,x,y21,x,y22,x,y31,x,y32,x,y41,x,y42,x,y51,x,y52,x,y61,x,y62)

运行结果如下:

图1.6.1 矩阵不同列维数对应按行遍历和按列遍历的时间
图1.6.1说明:
[1]图像横轴为矩阵列维数,分别为512,1024,2048,4096,8192,16384
[2]图像纵轴为遍历时间,单位为ms
[3]从下往上数依次为曲线1,2……12
[4]曲线1,3,5,7,9,11为矩阵行维数为512,1024,2048,4096,8192,16384时对应的按行遍历的时间
[5] 曲线2,4,6,8,10,12为矩阵行维数为512,1024,2048,4096,8192,16384时对应的按列遍历的时间
【2】 分区对比图

 x=[512 1024 2048 4096 8192 16384];
 y11=[0 1 1 6 11 22];
 y12=[2 7 14 34 90 176];
 subplot(2,3,1);
 plot(x,y11,x,y12);
 ylabel('矩阵行为512');

y21=[1 2 5 10 22 45];
y22=[4 13 34 83 179 365];
 subplot(2,3,4);
 plot(x,y21,x,y22);
 ylabel('矩阵行为1024');
 
y31=[1 4 15 22 44 94];
y32=[12 32 80 180 353 703];
 subplot(2,3,2);
 plot(x,y31,x,y32);
  ylabel('矩阵行为2048');
  
y41=[5 11 23 43 93 193];
y42=[25 68 151 346 720 1436];
 subplot(2,3,5);
 plot(x,y41,x,y42);
  ylabel('矩阵行为4096');
  
y51=[11 21 43 88 185 380];
y52=[63 143 289 701 1389 2854];
 subplot(2,3,3);
 plot(x,y51,x,y52);
  ylabel('矩阵行为8192');
  
y61=[22 44 89 179 387 724];
y62=[140 284 586 1399 2832 5651];
 subplot(2,3,6);
 plot(x,y61,x,y62);
 ylabel('矩阵行为16384');

运行结果如下:

图1.6.2 矩阵不同列维数对应按行遍历和按列遍历的时间

图1.6.2说明:
[1]图像横轴为矩阵列维数,分别为512,1024,2048,4096,8192,16384
[2]图像纵轴为遍历时间,单位为ms
[3]第一列的两个图像分别是矩阵行维数为512和1024时对应的按行访问和按列访问的曲线图,其中斜率较小的按行遍历的曲线
[4]第一列的两个图像分别是矩阵行维数为2048和4096时对应的按行访问和按列访问的曲线图,其中斜率较小的按行遍历的曲线
[5]第一列的两个图像分别是矩阵行维数为8192和16384时对应的按行访问和按列访问的曲线图,其中斜率较小的按行遍历的曲线
【3】 分析固定列数时不同行数对应遍历时间图:
简单用matlab绘制的散点曲线图,代码如下:

x=[512 1024 2048 4096 8192 16384];
y11=[0 1 1 5 11 22];
y12=[2 4 12 25 63 140];
y21=[1 2 4 11 21 44];
y22=[7 13 32 68 143 284];
y31=[1 5 15 23 43 89];
y32=[14 34 80 151 289 586];
y41=[6 10 22 43 88 179];
y42=[34 83 180 346 701 1399];
y51=[11 22 44 93 185 387];
y52=[90 179 353 720 1389 2832];
y61=[22 45 94 193 380 724];
y62=[176 365 703 1436 2854 5651];
 plot(x,y11,x,y12,x,y21,x,y22,x,y31,x,y32,x,y41,x,y42,x,y51,x,y52,x,y61,x,y62)

运行结果如下:

图1.6.3 矩阵不同行维数对应按行遍历和按列遍历的时间
图1.6.3说明:
[1]图像横轴为矩阵行维数,分别为512,1024,2048,4096,8192,16384
[2]图像纵轴为遍历时间,单位为ms
[3]从下往上数依次为曲线1,2……12
[4]曲线1,3,5,7,9,11为矩阵列维数为512,1024,2048,4096,8192,16384时对应的按行遍历的时间
[5] 曲线2,4,6,8,10,12为矩阵列维数为512,1024,2048,4096,8192,16384时对应的按列遍历的时间
【4】 分区对比图

x=[512 1024 2048 4096 8192 16384];
y11=[0 1 1 5 11 22];
y12=[2 4 12 25 63 140];
 subplot(2,3,1);
 plot(x,y11,x,y12);
 ylabel('矩阵列为512');

y21=[1 2 4 11 21 44];
y22=[7 13 32 68 143 284];
 subplot(2,3,4);
 plot(x,y21,x,y22);
 ylabel('矩阵列为1024');
 
y31=[1 5 15 23 43 89];
y32=[14 34 80 151 289 586];
 subplot(2,3,2);
 plot(x,y31,x,y32);
  ylabel('矩阵列为2048');
  
y41=[6 10 22 43 88 179];
y42=[34 83 180 346 701 1399];
 subplot(2,3,5);
 plot(x,y41,x,y42);
  ylabel('矩阵列为4096');
  
y51=[11 22 44 93 185 387];
y52=[90 179 353 720 1389 2832];
 subplot(2,3,3);
 plot(x,y51,x,y52);
  ylabel('矩阵列为8192');
  
y61=[22 45 94 193 380 724];
y62=[176 365 703 1436 2854 5651];
 subplot(2,3,6);
 plot(x,y61,x,y62);
 ylabel('矩阵列为16384');

运行结果如下:

图1.6.4 矩阵不同行维数对应按行遍历和按列遍历的时间
图1.6.4说明:
[1]图像横轴为矩阵行维数,分别为512,1024,2048,4096,8192,16384
[2]图像纵轴为遍历时间,单位为ms
[3]第一列的两个图像分别是矩阵列维数为512和1024时对应的按行访问和按列访问的曲线图,其中斜率较小的按行遍历的曲线
[4]第一列的两个图像分别是矩阵列维数为2048和4096时对应的按行访问和按列访问的曲线图,其中斜率较小的按行遍历的曲线
[5]第一列的两个图像分别是矩阵列维数为8192和16384时对应的按行访问和按列访问的曲线图,其中斜率较小的按行遍历的曲线
7)得出结论:
【1】按行遍历比按列遍历快。
【2】矩阵规模越大,按行遍历与按列遍历时间差异越显著。
8)理论解释:
【1】CPU高速缓存:维基百科中有以下的内容:CPU高速缓存(英语:CPU Cache,在本文中简称缓存)是用于减少处理器访问内存所需平均时间的部件。在金字塔式存储体系中它位于自顶向下的第二层,仅次于CPU寄存器。其容量远小于内存,但速度却可以接近处理器的频率。当处理器发出内存访问请求时,会先查看缓存内是否有请求数据。如果存在(命中),则不经访问内存直接返回该数据;如果不存在(失效),则要先把内存中的相应数据载入缓存,再将其返回处理器。
缓存从内存中抓取一般都是整个数据块,所以它的物理内存是连续的,几乎都是同行不同列的,而如果内循环以列的方式进行遍历的话,将会使整个缓存块无法被利用,而不得不从内存中读取数据,而从内存读取速度是远远小于从缓存中读取数据的。随着数组元素越来越多,按列读取速度也会越来越慢。
【2】分页调度:物理内存是以页的方式进行划分的,当一个二维数组很大是如 int[128][1024],假设一页的内存为4096个字节,而每一行正好占据内存的一页,如果以列的形式进行遍历,就会发生128*1024次的页面调度,而如果以行遍历则只有128次页面调度,而页面调度是有时间消耗的,因而调度次数越多,遍历的时间就越长。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用c语言写一个大规模矩阵遍历的程序,在不同规模的数据下运行,比较按行遍历快还是按列遍历快。 的相关文章

  • gamma校正

    伽玛校正 xff08 Gamma Correction xff09 校正的目的输入转至线性空间输出前进行校正衰减 校正的目的 保证所有的输入都转换到线性空间 xff0c 并在线性空间下做各种光照计算 xff08 线性空间进行操作 xff09
  • d3d11释放问题

    d3d11释放问题 释放过程中遇到明明已经调用release xff08 xff09 但是内存却没有下降 xff0c 后来查看了其计数器n发现其不为0 xff0c 也就是没释放干净 xff0c 只是内部引用数减1 span class to
  • imgui显示中文

    imgui显示中文 首先先加载中文字体 span class token comment Load Fonts span io span class token punctuation span Fonts span class token
  • serialVersionUID作用

    原文出处 xff1a 未知 Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的 在进行反序列化时 xff0c JVM会把传来的字节流中的serialVersionUID与本地相应实体 xff08 类
  • linux命令与makefile学习

    linux命令与makefile学习 文件权限通配符 常用命令查看CPU 内存占用makefilegcc与g 43 43 区别 xff1a Linux上有一句话 xff1a 一切皆文件 普通文件 目录文件 d xff08 directory
  • VS在输出窗口显示信息

    输出窗口的信息传给函数 xff0c 函数内部调用系统函数OutputDebugString xff0c 就可以把调试信息打印到输出窗口 span class token keyword void span span class token
  • 使用 nlohmann 解析 json 文件

    使用 nlohmann 解析 json 文件 nlohmann json的配置json基本数据结构json文件的读取 构造与输出C 43 43 对象与nlohmann json对象的转换C 43 43 对象转换成nlohmann json对
  • ImGui实现Button高亮

    ImGui实现Button高亮 记录下在ImGui中实现Button高亮的操作 xff0c 跟着官方demo走没看到具体的实现方式 xff0c 想着渲染是不断进行的 xff0c 让下一帧绘制上次选择的状态 结果如下 xff1a 部分代码 s
  • HLSL笔记

    常量缓冲区 Constant Buffer 常量缓冲区允许C 43 43 端将数据传递给HLSL中使用 xff0c 在HLSL端 xff0c 这些传递过来的数据不可更改 xff0c 因而是常量 常量缓冲区对这种使用方式有所优化 xff0c
  • opengl shader实现Bezier曲线

    opengl shader实现Bezier曲线 顶点着色器片段着色器向shader传递数据 顶点着色器 span class token keyword const span span class token keyword char sp
  • windows创建窗口

    windows创建窗口 CreateWindowW创建窗口句柄窗口可以调节尺寸以及移动完整代码窗口的效果创建指定画面大小 xff0c 不包含窗口栏尺寸且无法调整尺寸的窗口思考 一般来讲 xff0c 要绘制或者渲染目标物体首先需要创建窗口 x
  • makefile文件解释

    makefile文件解释 makefile文件详细解释 makefile文件 CC span class token operator 61 span g 43 43 PROGRAM span class token operator 61
  • python实现自动化鼠标点击

    python实现自动化鼠标点击 span class token keyword import span pyautogui span class token keyword import span time span class toke
  • opengles共享纹理

    OpenGL ES 3 0中引入的 外部纹理 xff08 External Textures xff09 扩展 xff0c 允许将OpenGL纹理对象绑定到由外部API创建的纹理对象 xff0c 例如相机采集到的图像 视频流或其他图像数据
  • https 证书工具 Letsencrypt 简单教程

    https取代http是大势所趋 xff0c https的好处本文不在赘述 xff0c 很多公司和机构都在推进这一进程 xff0c Apple公司甚至规定 xff0c iOS上的App应用必须使用https 因此 xff0c 正是受到App
  • Linux简单命令使用笔记

    之前一直用虚拟机 xff0c 其实购买一台阿里云服务器学习linxu更加的方便快捷 阿里云服务器购买 1 electerm连接登录linux SecureCRT和SFTP 最近linux连接工具electerm 上面是两款不同的连接linu
  • 软件工程的十大模型

    1 软件生命周期模型 软件生命周期由软件定义 软件开发与运维 xff08 也称软件维护 xff09 3个时期组成 xff0c 每个时期又进一步划分成若干个阶段 问题定义 xff1a 要解决的问题是什么 xff1f 通过对客户的访问调查 xf
  • WEEK6 限时测试A - 掌握魔法の东东 II

    A 掌握魔法 东东 II 题目描述 从瑞神家打牌回来后 xff0c 东东痛定思痛 xff0c 决定苦练牌技 xff0c 终成赌神 xff01 东东有 A B 张扑克牌 每张扑克牌有一个大小 整数 xff0c 记为a xff0c 范围区间是
  • WEEK13 作业 A - TT 的神秘任务1(必做)

    A TT 的神秘任务1 xff08 必做 xff09 题目描述 这一天 xff0c TT 遇到了一个神秘人 神秘人给了两个数字 xff0c 分别表示 n 和 k xff0c 并要求 TT 给出 k 个奇偶性相同的正整数 xff0c 使得其和
  • WEEK14 作业 C - Q老师的考验(必做)

    C Q老师的考验 xff08 必做 xff09 题目描述 Q老师 对数列有一种非同一般的热爱 xff0c 尤其是优美的斐波那契数列 这一天 xff0c Q老师 为了增强大家对于斐波那契数列的理解 xff0c 决定在斐波那契的基础上创建一个新

随机推荐

  • 程序设计与实践 模拟题四 201809-3 元素选择器

    201809 3 元素选择器 题目描述 题解 本题是一道思维难度不大的模拟题 实现过程和思想都比较简单 xff0c 具体实现比较难 xff0c 认真仔细即可 xff08 但是自己一开始写的代码只得了80分 xff0c 又比较了其他人的代码才
  • idea中添加maven远程仓库

    idea无法自动下载依赖的解决方法 xff1a 1 xff1a 选择自己的maven目录 配置文件setting xml和仓库repository xff0c 并勾选2个Override 2 点击Runner 在VM Options那一行添
  • 详解C++中的指针结构体数组以及指向结构体变量的指针

    这篇文章主要介绍了C 43 43 中的指针结构体数组以及指向结构体变量的指针的用法 是C 43 43 入门学习中的基础知识 需要的朋友可以参考下 C 43 43 结构体数组 一个结构体变量中可以存放一组数据 xff08 如一个学生的学号 姓
  • bad substitution

    初接触shell脚本 xff0c 在vim中写代码 xff0c 出现了好几次 Bad substitution 我的错误有两种 xff1a 开始的的指定脚本环境 应该是 bin bash 在编译运行时 也应该用 bash 的使用错误 xff
  • Re.从零开始--基于UbuntuServer 20.04-OpenStack平台搭建_

    基于UbuntuServer 20 04 OpenStack平台搭建 前言 xff1a 本文档基于ubuntu server20 04版本和OpenStack Victoria搭建openstack环境 部署最小化Ubuntu openst
  • win10系统vvv连接不上,提示:“在连接完成前,连接被远程计算机终止”的解决办法

    进入 控制面板 网络和共享中心 更改适配器设置 右键点 vvv连接 属性 安全 选择 允许使用这些协议 xff0c 以下选项全部打勾即可 未加密的密码 质询握手身份验证协议 Microsoft CHAP Version2
  • CSP 2021 S组游记

    这是异想之旅的一篇水文 xff0c 技术无关 占个坑 xff0c 晚上更新 说说初赛 xff1a 我的竞赛老师是很重视初赛的 xff0c 整个暑假一半的时间集训 xff0c 而一半的集训时间都是面对初赛 模拟题大家做的量不同 xff0c 但
  • linux命令解压压缩rar文件的详细步骤

    一 widonds下打包rar文件并上传 yum install lrzsz rz test rar 二 下载并安装rar软件 2 1 下载 mkdir p home oldboy tools cd home oldboy tools wg
  • 配置pvst详解

    配置 pvst 在学习pvst之前 xff0c 先要学习一下stp STP生成树 思科默认有stp配置 1 选择根网桥 xff08 root bridge xff09 xff08 这个是必须的配置 xff09 选择根网桥的依据是网桥ID x
  • (真)手把手教你配置Ubuntu大数据Hadoop环境

    目录 一 前期准备 VMware tools安装 基本配置 root配置 网络配置 软件源配置 二 创建hadoop用户和文件 用户创建 小插曲 三 FTP配置 四 配置java环境及安装eclipse 安装eclipse 安装java环境
  • Ubuntu安装配置hbase完美解决方案

    目录 一 解决版本号打印失败问题 二 配置伪分布式 三 运行简单的hbase shell命令 这篇文章需要配合前一篇文章一起食用更加美味 xff08 真 xff09 手把手教你配置Ubuntu大数据Hadoop环境 一 解决版本号打印失败问
  • Linux shell实现阶乘

    bin sh read p 34 请输入想计算的数字 34 num 首先定义一个num参数接受为命令行的第一个参数 expr num 43 1 amp gt dev null 利用expr计算时参数必须是整数的原则 xff0c 如果返回零则
  • DHCP服务器搭建

    DHCP服务器搭建 安装dhcp服务器 使用yum y install dhcp 命令安装dhcp服务 修改配置文件 修改最大租约和默认租约为8天和2天 修改地址池 网关地址 以及子网掩码相关配置 总配置如下 Dhcp服务启动成功
  • idea使用技巧

    idea使用技巧 快速创建测试类 找到你想要测试的类 xff0c 按下crtl 43 shift 43 t或者右键 之后就会自动在maven的test xff08 只要是符合maven规约的文件即可 xff09 里面添加相应的测试类 测试类
  • Spring Tools Suit 4

    Spring Tools Suit 4使用手册 最近公司不让用破解版的idea xff0c 被迫转为eclipse xff0c 又因为项目大多都是spring的 xff0c 所以用spring封装好的Spring Tool Suite 4简
  • 基于Debian的发行版有哪些

    基于Debian的发行版有哪些 原创2023 04 05 08 24 贺浦力特 Debian 是一款由志愿者开发者团队创建 持续开发和维护的自由 开源的操作系统 xff0c 它以稳定 可靠和安全而著称 Debian 采用 apt 包管理工具
  • 修改JLabel背景色

    如何修改JLabel背景色 xff1f 搞笑 JLabel label 61 new JLabel label setBackground Color RED it does not work 当我们把JLabel控件加载到JPanel控件
  • Linux上启动盘制作工具大比拼

    启动盘制作工具是一种软件 xff0c 它可以帮助您将ISO镜像文件 xff0c 如Windows操作系统安装程序 xff0c 制作成可启动的U盘或光盘 xff0c 以便在需要安装操作系统或修复系统时使用 windows上制作启动盘的工具有很
  • IDEA连接SVN服务器地址拉代码,报错提示E230001: Server SSL certificate verification failed: certificate issued“验证失败问题

    问题描述 今天在使用idea拉取svn代码的时候无法操作 提示E230001 Server SSL certificate verification failed certificate issued xff0c 原因是由于SVNssl证书
  • 用c语言写一个大规模矩阵遍历的程序,在不同规模的数据下运行,比较按行遍历快还是按列遍历快。

    用c语言写一个大规模矩阵遍历的程序 xff0c 在不同规模的数据下运行 xff0c 比较按行遍历快还是按列遍历快 1 xff09 本题老师的考察点 xff1a 矩阵在计算机内存储的方式 2 xff09 解答本题时遇到的一些问题 xff1a