当前位置:   article > 正文

什么是IO密集型和CPU密集型以及在并行开发是需要注意的(1、2、3、4)

什么是io密集型

IO密集型和CPU密集型

1. 两者的区别

1.1 什么是IO,什么是IO操作

  • 什么是IO
    I/O输入/输出(Input/Output),分为IO设备和IO接口两个部分

  • 什么是IO操作

处理器访问任何寄存器和 Cache 等封装以外的数据资源都可以当成 I/O 操作,包括内存,磁盘,显卡等外部设备。

计算机的核心部件是计算单元,即CPU,相对于CPU来说,存储(访问内存)、接口(访问外设)都是I/O。

1.2 什么是IO密集型操作

IO密集型操作(I/O bound)

IO密集型指的是系统的CPU性能相对硬盘、内存要好很多,此时,系统运作,大部分的状况是CPU在等I/O (硬盘/内存) 的读/写操作,此时CPU Loading并不高。

I/O bound的程序一般在达到性能极限时,CPU占用率仍然较低。这可能是因为任务本身需要大量I/O操作,而pipeline做得不是很好,没有充分利用处理器能力。

1.3 什么是CPU密集型

CPU密集型(CPU-bound)

CPU密集型也叫计算密集型,指的是系统的硬盘、内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/内存),I/O在很短的时间就可以完成,而CPU还有许多运算要处理,CPU Loading很高。

IO密集型 VS CPU密集型

计算密集型任务由于主要消耗CPU资源,因此,代码运行效率至关重要。Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。

2. 使用C#代码说明两者的区别

2.1 代码说明

  1. 使用串行代码(不开启线程)拷贝文件并在拷贝完成之后将文件删除
  2. 使用并行(开启线程)拷贝文件并在拷贝完成之后将文件删除
  3. 使用两种文件数据:一种文件比较大,另一种文件比较零碎

2.2 代码粘贴

  • 界面代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace IOIntensiveDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnSingleThreadOperation_Click(object sender, EventArgs e)
        {
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();

            Console.WriteLine("********************************单线程复制文件***********************************");

            string strSorcePath = tbSourcePath.Text;
            string strTargetPath = tbTargetPath.Text;

            for (int i = 0; i < 10; i++)
            {
                CopyFolder(strSorcePath, strTargetPath, i);
            }
        }

        private void CopyFolder(string strSorcePath, string strTargetPath, int i)
        {
            Console.WriteLine($"拷贝数据{i}开始:当前线程{Thread.CurrentThread.ManagedThreadId},开始时间:{DateTime.Now}");
            strTargetPath = System.IO.Path.Combine(strTargetPath,i.ToString());
            FileAPI.CopyDirectory(strSorcePath, strTargetPath);
            System.IO.Directory.Delete(strTargetPath,true);
            Console.WriteLine($"拷贝数据{i}完成:当前线程{Thread.CurrentThread.ManagedThreadId},开始时间:{DateTime.Now}");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();

            Console.WriteLine("********************************多线程复制文件***********************************");
            string strSorcePath = tbSourcePath.Text;
            string strTargetPath = tbTargetPath.Text;
            for (int i = 0; i < 10; i++)
            {
                int num = i;
                Task task = new Task(() => this.CopyFolder(strSorcePath, strTargetPath, num));
                task.Start();
            }
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 粘贴文件代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace IOIntensiveDemo
{
    /// <summary>
    /// 文件操作帮助类
    /// </summary>
    public class FileAPI
    {
        /// <summary>
        /// 拷贝文件夹
        /// </summary>
        /// <param name="srcPath"></param>
        /// <param name="destPath"></param>
        public static void CopyDirectory(string srcPath, string destPath)
        {
            try
            {
                if (!Directory.Exists(destPath))
                {
                    Directory.CreateDirectory(destPath);
                }
                List<string> listFolderPath =System.IO.Directory.GetDirectories(srcPath, "*", SearchOption.AllDirectories).ToList();
                listFolderPath=listFolderPath.OrderByDescending(a => a.Length).ToList();
                foreach (var item in listFolderPath)
                {
                    string strTargetPath = System.IO.Path.Combine(destPath, item.Substring(srcPath.Length + 1));
                    System.IO.Directory.CreateDirectory(strTargetPath);
                }
                List<string> listFilePath = System.IO.Directory.GetFiles(srcPath, "*", SearchOption.AllDirectories).ToList();
                int index = 0;
                foreach (var item in listFilePath)
                {
                    index++;
                    string strTargetPath = System.IO.Path.Combine(destPath, item.Substring(srcPath.Length+1));
                    System.IO.File.Copy(item, strTargetPath);
                }
            }
            catch (Exception ex)
            {
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

2.3 两类数据说明

  1. 文件比较零碎

在这里插入图片描述

  1. 文件比较大,并且比较单一

在这里插入图片描述

2.4 两类数据执行代码过程中的细节

2.4.1 文件比较大,并且比较单一

2.4.1.1 单线程运行细节
    1. 运行细节

在这里插入图片描述

    1. 运行完毕耗时:总耗时:4分10秒-250s(总觉得在骂我自己)

在这里插入图片描述

2.4.1.2 多线程运行细节
    1. 运行细节

在这里插入图片描述

    1. 运行完毕耗时:总耗时:1分30秒-90s

在这里插入图片描述

2.4.2 文件比较大,并且比较单一

2.4.2.1 单线程运行细节

在这里插入图片描述

    1. 运行完毕耗时:总耗时:1分33秒-93s

在这里插入图片描述

2.4.2.2 多线程运行细节
    1. 运行细节

在这里插入图片描述

    1. 运行完毕耗时:总耗时:1分30秒-90s

在这里插入图片描述

2.4 结论

前后呼应一下:

  1. 所谓的IO密集型操作时操作过程中IO操作密集,比如【2.4.2】 在大文件拷贝时IO操作过载,CPU操作明显处于富余的情况,在此类情况下多线程无法提升效率,甚至会比单线程还要慢,原因时文件在拷贝过程中频繁切换CPU时间片,需要不断的寻址,导致效率低下,此类情况下单线程效率要优于或持平多线程

  2. 所谓CPU密集型是指操作过程中CPU操作密集,比如【2.4.1】 尽管在拷贝文件过程中文件拷贝较多,但是拷贝速度太快,并没有文件拷贝持有IO操作,此时CPU操作明显处于过载情况,此类情况下多线程效率要优于单线程

  3. 对于IO密集型建议使用脚本语言进行编码,比如python,相对编码简单,编码效率快

  4. 对于CPU密集型建议使用编译型语言进行编码,比如C、C++、Java和C#

效率低下,此类情况下单线程效率要优于或持平多线程

  1. 所谓CPU密集型是指操作过程中CPU操作密集,比如【2.4.1】 尽管在拷贝文件过程中文件拷贝较多,但是拷贝速度太快,并没有文件拷贝持有IO操作,此时CPU操作明显处于过载情况,此类情况下多线程效率要优于单线程

  2. 对于IO密集型建议使用脚本语言进行编码,比如python,相对编码简单,编码效率快

  3. 对于CPU密集型建议使用编译型语言进行编码,比如C、C++、Java和C#

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/952276
推荐阅读
相关标签
  

闽ICP备14008679号