• 并行工作


    调度工作,只能有一个工作做一个任务。在游戏中,通常希望对大量对象执行相同的操作。有一个名为IJobParallelFor的独立作业类型来处理这个问题。

    注意:“ParallelFor”作业是Unity中用于实现IJobParallelFor接口的任何结构的集合术语。

    ParallelFor作业使用NativeArray数据作为其数据源。ParallelFor作业跨多个核心运行。每个核心有一个作业,每个作业处理一部分工作量。IJobParallelFor表现得像IJob,但它不是单个Execute方法,而是Execute在数据源中的每个项目上调用一次方法。方法中有一个整数参数Execute。该索引用于访问和操作作业实现中的数据源的单个元素。

    ParallelFor作业定义的示例:

    struct IncrementByDeltaTimeJob: IJobParallelFor
    {
        public NativeArray<float> values;
        public float deltaTime;
    
        public void Execute (int index)
        {
            float temp = values[index];
            temp += deltaTime;
            values[index] = temp;
        }
    }
    

    调度ParallelFor作业

    在调度ParallelFor作业时,必须指定NativeArray要拆分的数据源的长度。NativeArray如果结构中有多个,Unity C#作业系统无法知道您要将哪个用作数据源。长度还告诉C#作业系统需要多少Execute方法。


    幕后花絮,ParallelFor作业的调度更复杂。在调度ParallelFor作业时,C#作业系统将工作分成批处理以在核心之间分配。每批包含一组Execute方法。然后,C#作业系统在每个CPU核心的Unity本机作业系统中调度最多一个作业,并将该本机作业通过一些批次来完成。

    ParallelFor在核心之间划分批次的作业


    当本地作业在其他作业之前完成其批处理时,它会从其他本机作业中窃取剩余批处理。它一次只能窃取本机作业剩余批次的一半,以确保缓存局部性

    要优化过程,您需要指定批次计数。批次计数控制您获得的作业数量,以及线程之间工作重新分配的细化程度。批量计数较低(例如1)可以使线程之间的工作分布更均匀。它确实带来了一些开销,所以有时候增加批量计数会更好。从1开始并增加批次计数直到可忽略不计的性能增益是一种有效的策略。

    调度ParallelFor作业的示例

    工作代码

    // Job adding two floating point values together
    public struct MyParallelJob : IJobParallelFor
    {
        [ReadOnly]
        public NativeArray<float> a;
        [ReadOnly]
        public NativeArray<float> b;
        public NativeArray<float> result;
    
        public void Execute(int i)
        {
            result[i] = a[i] + b[i];
        }
    }
    

    主线程代码

    NativeArray<float> a = new NativeArray<float>(2, Allocator.TempJob);
    
    NativeArray<float> b = new NativeArray<float>(2, Allocator.TempJob);
    
    NativeArray<float> result = new NativeArray<float>(2, Allocator.TempJob);
    
    a[0] = 1.1;
    b[0] = 2.2;
    a[1] = 3.3;
    b[1] = 4.4;
    
    MyParallelJob jobData = new MyParallelJob();
    jobData.a = a;  
    jobData.b = b;
    jobData.result = result;
    
    // Schedule the job with one Execute per index in the results array and only 1 item per processing batch
    JobHandle handle = jobData.Schedule(result.Length, 1);
    
    // Wait for the job to complete
    handle.Complete();
    
    // Free the memory allocated by the arrays
    a.Dispose();
    b.Dispose();
    result.Dispose();
  • 相关阅读:
    字符串与Unicode码的相互转换
    关于es6中的yield
    ajax请求中的6个全局事件
    用H5上传文件
    类型化数组
    git笔记-9-29
    js正则表达式验证身份证号和密码
    assertThat用法
    java产生随机数的几种方式
    jQuery之Deferred对象详解
  • 原文地址:https://www.cnblogs.com/longsl/p/11314543.html
Copyright © 2020-2023  润新知