区块链技术博客
www.b2bchain.cn

在GPU上执行计算求职学习资料

本文介绍了在GPU上执行计算求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

Performing Calculations on a GPU | Apple Developer Documentation

使用Metal在GPU上进行计算。

通过一个简单示例,把一个C语言逻辑转换成着色器,最终使用GPU执行自定义计算,并获取其结果。

翻译术语表

概述

在本示例中,你将学习所有Metal app中使用的基本任务。你将看到如何把C编写的简单函数转为Metal着色器语言(MSL),以在GPU上运行。你将获取一个GPU,通过创建管线,并创建可供GPU访问的数据对象,把MSL函数在其运行。为了针对你的数据执行管线,你需要创建一个命令缓冲区(command buffer),把命令写入其中,并将缓冲区提交到命令队列。Metal会将命令发送到GPU上执行。

编写一个GPU函数来执行计算

为了说明GPU编程,这个程序只是简单把两个数组的对应元素相加,并将结果写入第三个数组。清单1使用C语言实现该程序,在CPU上执行。

清单1 数组相加,使用C语言编写

void add_arrays(const float* inA,                 const float* inB,                 float* result,                 int length) {     for (int index = 0; index < length ; index++)     {         result[index] = inA[index] + inB[index];     } }

因为每个值都是独立计算的,所以可以安全地同时计算这些值。因为要在GPU上执行计算,需要用Metal着色器语言重写这个函数。MSL是C++的一个变种,专为GPU编程而设计的语言。在Metal中,在GPU运行的代码称为着色器(shader),因为历史上它们最早被用于计算3D图形中的颜色。清单2展示了MSL编写的着色器,它执行的计算与清单1相同。对应示例项目中的add.metal文件中。Xcode会在应用程序target中构建所有的.metal文件,创建一个默认的Metal库,并将其嵌入到你的程序包中。后面会讲到如何加载默认库。

清单2 数组相加,使用MSL编写

kernel void add_arrays(device const float* inA,                        device const float* inB,                        device float* result,                        uint index [[thread_position_in_grid]]) {     // the for-loop is replaced with a collection of threads, each of which     // calls this function.     result[index] = inA[index] + inB[index]; }

清单1和清单2很相似,但MSL上有些重要的区别。仔细看清单2。

首先,函数增加了kernel关键字,它声明该函数是:

  • 公共的GPU函数(public GPU function)。公共函数是你的应用程序中唯一能看到的函数。公共函数不能被其他着色器函数调用。
  • 计算型函数(compute function)(也称为计算型内核),它使用线程网格(grid of threads)进行并行计算。

参阅《Using a Render Pipeline to Render Primitives》,了解用于声明公共图形函数的其他函数关键字。

add_arrays函数用device关键字声明了它的三个参数,表示这些指针在device地址空间。MSL为内存定义了几个相互隔离的地址空间。每当在MSL中声明一个指针时,必须提供一个关键字来声明它的地址空间。使用device地址空间,表示这是一块GPU可以读写的持久性内存。

清单2删除了清单1中的for循环,因为该函数现在被计算网格中的多个线程调用。示例创建了一个与数组大小完全匹配的一维线程网格,因此数组中的每一项都由不同的线程计算。

为了替换之前由for循环提供的索引,函数增加一个新的index参数,并使用C++属性语法指定另一个MSL关键字,thread_position_in_grid。这个关键字声明了Metal应该为每个线程计算一个唯一的索引,并通过该参数传递该索引。因为add_arrays使用的是一维网格,所以索引被定义为一个标量整数(scalar integer)。即使删除了循环,清单1和清单2还是使用相同的代码将两个数字相加。如果你想把类似的代码从C或C++转换称MSL,请用同样的方法把循环逻辑替换成网格形式。

获取GPU

在程序中,MTLDevice对象是一个GPU的精简抽象,你可以用它来与GPU通信。Metal为每个GPU创建了一个MTLDevice对象。通过调用MTLCreateSystemDefaultDevice获得默认的设备对象。在macOS中,一个Mac可以有多个GPU,Metal选择其中一个作为默认值,并返回该GPU的设备对象。在macOS中,Metal还提供了其他的API,可以用它独立检索所有的设备对象,但本示例只是使用默认的设备对象。

id<MTLDevice> device = MTLCreateSystemDefaultDevice();

初始化Metal对象

Metal将其他GPU相关的实体都表示为对象,如已编译的着色器、内存缓冲区和纹理。要创建这些GPU特定对象,可以调用MTLDevice的对应的类方法或对象方法。一个设备对象只能使用由其自身直接或间接创建的实体对象。使用多个GPU的应用程序将使用多个设备对象,并为每个设备对象创建类似的Metal对象层次结构。

示例程序使用一个自定义的MetalAdder类来管理需要与GPU通信的对象。该类的构造器创建了这些对象,并将其存储在其属性中。程序创建该类的一个实例,传入Metal设备对象,用于创建辅助对象。MetalAdder对象保持对Metal对象的强引用,直到它执行完毕。

MetalAdder* adder = [[MetalAdder alloc] initWithDevice:device];

在Metal,类似这样的昂贵的构造任务可以一次执行,然后重用其结果。你很少需要在性能敏感的代码中运行这样的任务。

获取Metal函数的引用

构造器做的第一件事是加载函数, 并准备在GPU上运行。当在构建程序时,Xcode会编译add_arrays函数,将其添加到一个默认的Metal库中,并嵌入到程序包中。可以使用MTLLibraryMTLFunction对象来获取Metal库和其中包含的函数信息。要获得add_arrays函数,调用MTLDevice为默认库创建一个MTLLibrary对象,然后向库获取代表着色器函数的MTLFunction对象。

- (instancetype) initWithDevice: (id<MTLDevice>) device {     self = [super init];     if (self)     {         _mDevice = device;          NSError* error = nil;          // Load the shader files with a .metal file extension in the project          id<MTLLibrary> defaultLibrary = [_mDevice newDefaultLibrary];         if (defaultLibrary == nil)         {             NSLog(@"Failed to find the default library.");             return nil;         }          id<MTLFunction> addFunction = [defaultLibrary newFunctionWithName:@"add_arrays"];         if (addFunction == nil)         {             NSLog(@"Failed to find the adder function.");             return nil;         }

准备Metal管线

该函数对象是MSL函数的代理,但它不是可执行的代码。你可以通过创建一个管线(pipeline)把函数转换成可执行的代码。一个管线指定了GPU为完成一个特定任务而执行的步骤。在Metal中,一个管线由一个管线状态对象(pipeline state object)表示。因为这个示例使用了一个计算型函数,所以程序对应地创建了一个MTLComputePipelineState对象。

_mAddFunctionPSO = [_mDevice newComputePipelineStateWithFunction: addFunction error:&error];

一个计算型管线运行一个计算型函数,在运行函数之前可以选择对输入数据进行操作,在运行函数之后对输出数据进行操作。

当你创建一个管线状态对象时,设备对象会完成对这个特定GPU的函数编译。本示例同步创建了管线状态对象,并直接返回给应用程序。因为编译确实需要一定时间,所以避免在性能敏感的代码中同步创建管线状态对象。

注意

在目前给出的代码中,Metal返回的所有对象都是作为遵守协议的对象返回的。Metal用协议定义了大多数GPU特定的对象,以抽象出底层的实现类,这其具体实现可能会因不同的GPU而有所不同。Metal使用类定义与GPU无关的对象。任何一个给定的Metal协议的参考文档都会明确你是否可以在你的应用中实现该协议。

创建命令队列

要向GPU发送命令,你需要一个命令队列。Metal使用命令队列来调度命令。用MTLDevice创建一个命令对象。

_mCommandQueue = [_mDevice newCommandQueue];

创建数据缓冲区并加载数据

在初始化基本的Metal对象后,要为GPU加载数据来执行着色器程序。这个任务对性能的要求不高,但在程序启动初期来完成该操作还是很有帮助的。

GPU可以有自己专用的内存,也可以与操作系统共享内存。当你把数据存储在内存,并让数据在GPU可用时,Metal和操作系统内核需要执行额外的工作。Metal使用资源对象(MTLResource)抽象了这种内存管理。资源是GPU在运行命令时可以访问的已分配内存。使用MTLDevice为GPU创建资源。

示例程序创建了三个缓冲区,并在前两个缓冲区中填充随机数据。第三个缓冲区是add_arrays存储其结果的地方。

“`
_mBufferA = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared];
_mBufferB = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared];

Performing Calculations on a GPU | Apple Developer Documentation

使用Metal在GPU上进行计算。

通过一个简单示例,把一个C语言逻辑转换成着色器,最终使用GPU执行自定义计算,并获取其结果。

翻译术语表

概述

在本示例中,你将学习所有Metal app中使用的基本任务。你将看到如何把C编写的简单函数转为Metal着色器语言(MSL),以在GPU上运行。你将获取一个GPU,通过创建管线,并创建可供GPU访问的数据对象,把MSL函数在其运行。为了针对你的数据执行管线,你需要创建一个命令缓冲区(command buffer),把命令写入其中,并将缓冲区提交到命令队列。Metal会将命令发送到GPU上执行。

编写一个GPU函数来执行计算

为了说明GPU编程,这个程序只是简单把两个数组的对应元素相加,并将结果写入第三个数组。清单1使用C语言实现该程序,在CPU上执行。

清单1 数组相加,使用C语言编写

void add_arrays(const float* inA,                 const float* inB,                 float* result,                 int length) {     for (int index = 0; index < length ; index++)     {         result[index] = inA[index] + inB[index];     } }

因为每个值都是独立计算的,所以可以安全地同时计算这些值。因为要在GPU上执行计算,需要用Metal着色器语言重写这个函数。MSL是C++的一个变种,专为GPU编程而设计的语言。在Metal中,在GPU运行的代码称为着色器(shader),因为历史上它们最早被用于计算3D图形中的颜色。清单2展示了MSL编写的着色器,它执行的计算与清单1相同。对应示例项目中的add.metal文件中。Xcode会在应用程序target中构建所有的.metal文件,创建一个默认的Metal库,并将其嵌入到你的程序包中。后面会讲到如何加载默认库。

清单2 数组相加,使用MSL编写

kernel void add_arrays(device const float* inA,                        device const float* inB,                        device float* result,                        uint index [[thread_position_in_grid]]) {     // the for-loop is replaced with a collection of threads, each of which     // calls this function.     result[index] = inA[index] + inB[index]; }

清单1和清单2很相似,但MSL上有些重要的区别。仔细看清单2。

首先,函数增加了kernel关键字,它声明该函数是:

  • 公共的GPU函数(public GPU function)。公共函数是你的应用程序中唯一能看到的函数。公共函数不能被其他着色器函数调用。
  • 计算型函数(compute function)(也称为计算型内核),它使用线程网格(grid of threads)进行并行计算。

参阅《Using a Render Pipeline to Render Primitives》,了解用于声明公共图形函数的其他函数关键字。

add_arrays函数用device关键字声明了它的三个参数,表示这些指针在device地址空间。MSL为内存定义了几个相互隔离的地址空间。每当在MSL中声明一个指针时,必须提供一个关键字来声明它的地址空间。使用device地址空间,表示这是一块GPU可以读写的持久性内存。

清单2删除了清单1中的for循环,因为该函数现在被计算网格中的多个线程调用。示例创建了一个与数组大小完全匹配的一维线程网格,因此数组中的每一项都由不同的线程计算。

为了替换之前由for循环提供的索引,函数增加一个新的index参数,并使用C++属性语法指定另一个MSL关键字,thread_position_in_grid。这个关键字声明了Metal应该为每个线程计算一个唯一的索引,并通过该参数传递该索引。因为add_arrays使用的是一维网格,所以索引被定义为一个标量整数(scalar integer)。即使删除了循环,清单1和清单2还是使用相同的代码将两个数字相加。如果你想把类似的代码从C或C++转换称MSL,请用同样的方法把循环逻辑替换成网格形式。

获取GPU

在程序中,MTLDevice对象是一个GPU的精简抽象,你可以用它来与GPU通信。Metal为每个GPU创建了一个MTLDevice对象。通过调用MTLCreateSystemDefaultDevice获得默认的设备对象。在macOS中,一个Mac可以有多个GPU,Metal选择其中一个作为默认值,并返回该GPU的设备对象。在macOS中,Metal还提供了其他的API,可以用它独立检索所有的设备对象,但本示例只是使用默认的设备对象。

id<MTLDevice> device = MTLCreateSystemDefaultDevice();

初始化Metal对象

Metal将其他GPU相关的实体都表示为对象,如已编译的着色器、内存缓冲区和纹理。要创建这些GPU特定对象,可以调用MTLDevice的对应的类方法或对象方法。一个设备对象只能使用由其自身直接或间接创建的实体对象。使用多个GPU的应用程序将使用多个设备对象,并为每个设备对象创建类似的Metal对象层次结构。

示例程序使用一个自定义的MetalAdder类来管理需要与GPU通信的对象。该类的构造器创建了这些对象,并将其存储在其属性中。程序创建该类的一个实例,传入Metal设备对象,用于创建辅助对象。MetalAdder对象保持对Metal对象的强引用,直到它执行完毕。

MetalAdder* adder = [[MetalAdder alloc] initWithDevice:device];

在Metal,类似这样的昂贵的构造任务可以一次执行,然后重用其结果。你很少需要在性能敏感的代码中运行这样的任务。

获取Metal函数的引用

构造器做的第一件事是加载函数, 并准备在GPU上运行。当在构建程序时,Xcode会编译add_arrays函数,将其添加到一个默认的Metal库中,并嵌入到程序包中。可以使用MTLLibraryMTLFunction对象来获取Metal库和其中包含的函数信息。要获得add_arrays函数,调用MTLDevice为默认库创建一个MTLLibrary对象,然后向库获取代表着色器函数的MTLFunction对象。

- (instancetype) initWithDevice: (id<MTLDevice>) device {     self = [super init];     if (self)     {         _mDevice = device;          NSError* error = nil;          // Load the shader files with a .metal file extension in the project          id<MTLLibrary> defaultLibrary = [_mDevice newDefaultLibrary];         if (defaultLibrary == nil)         {             NSLog(@"Failed to find the default library.");             return nil;         }          id<MTLFunction> addFunction = [defaultLibrary newFunctionWithName:@"add_arrays"];         if (addFunction == nil)         {             NSLog(@"Failed to find the adder function.");             return nil;         }

准备Metal管线

该函数对象是MSL函数的代理,但它不是可执行的代码。你可以通过创建一个管线(pipeline)把函数转换成可执行的代码。一个管线指定了GPU为完成一个特定任务而执行的步骤。在Metal中,一个管线由一个管线状态对象(pipeline state object)表示。因为这个示例使用了一个计算型函数,所以程序对应地创建了一个MTLComputePipelineState对象。

_mAddFunctionPSO = [_mDevice newComputePipelineStateWithFunction: addFunction error:&error];

一个计算型管线运行一个计算型函数,在运行函数之前可以选择对输入数据进行操作,在运行函数之后对输出数据进行操作。

当你创建一个管线状态对象时,设备对象会完成对这个特定GPU的函数编译。本示例同步创建了管线状态对象,并直接返回给应用程序。因为编译确实需要一定时间,所以避免在性能敏感的代码中同步创建管线状态对象。

注意

在目前给出的代码中,Metal返回的所有对象都是作为遵守协议的对象返回的。Metal用协议定义了大多数GPU特定的对象,以抽象出底层的实现类,这其具体实现可能会因不同的GPU而有所不同。Metal使用类定义与GPU无关的对象。任何一个给定的Metal协议的参考文档都会明确你是否可以在你的应用中实现该协议。

创建命令队列

要向GPU发送命令,你需要一个命令队列。Metal使用命令队列来调度命令。用MTLDevice创建一个命令对象。

_mCommandQueue = [_mDevice newCommandQueue];

创建数据缓冲区并加载数据

在初始化基本的Metal对象后,要为GPU加载数据来执行着色器程序。这个任务对性能的要求不高,但在程序启动初期来完成该操作还是很有帮助的。

GPU可以有自己专用的内存,也可以与操作系统共享内存。当你把数据存储在内存,并让数据在GPU可用时,Metal和操作系统内核需要执行额外的工作。Metal使用资源对象(MTLResource)抽象了这种内存管理。资源是GPU在运行命令时可以访问的已分配内存。使用MTLDevice为GPU创建资源。

示例程序创建了三个缓冲区,并在前两个缓冲区中填充随机数据。第三个缓冲区是add_arrays存储其结果的地方。

“`
_mBufferA = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared];
_mBufferB = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared];

Performing Calculations on a GPU | Apple Developer Documentation

使用Metal在GPU上进行计算。

通过一个简单示例,把一个C语言逻辑转换成着色器,最终使用GPU执行自定义计算,并获取其结果。

翻译术语表

概述

在本示例中,你将学习所有Metal app中使用的基本任务。你将看到如何把C编写的简单函数转为Metal着色器语言(MSL),以在GPU上运行。你将获取一个GPU,通过创建管线,并创建可供GPU访问的数据对象,把MSL函数在其运行。为了针对你的数据执行管线,你需要创建一个命令缓冲区(command buffer),把命令写入其中,并将缓冲区提交到命令队列。Metal会将命令发送到GPU上执行。

编写一个GPU函数来执行计算

为了说明GPU编程,这个程序只是简单把两个数组的对应元素相加,并将结果写入第三个数组。清单1使用C语言实现该程序,在CPU上执行。

清单1 数组相加,使用C语言编写

void add_arrays(const float* inA,                 const float* inB,                 float* result,                 int length) {     for (int index = 0; index < length ; index++)     {         result[index] = inA[index] + inB[index];     } }

因为每个值都是独立计算的,所以可以安全地同时计算这些值。因为要在GPU上执行计算,需要用Metal着色器语言重写这个函数。MSL是C++的一个变种,专为GPU编程而设计的语言。在Metal中,在GPU运行的代码称为着色器(shader),因为历史上它们最早被用于计算3D图形中的颜色。清单2展示了MSL编写的着色器,它执行的计算与清单1相同。对应示例项目中的add.metal文件中。Xcode会在应用程序target中构建所有的.metal文件,创建一个默认的Metal库,并将其嵌入到你的程序包中。后面会讲到如何加载默认库。

清单2 数组相加,使用MSL编写

kernel void add_arrays(device const float* inA,                        device const float* inB,                        device float* result,                        uint index [[thread_position_in_grid]]) {     // the for-loop is replaced with a collection of threads, each of which     // calls this function.     result[index] = inA[index] + inB[index]; }

清单1和清单2很相似,但MSL上有些重要的区别。仔细看清单2。

首先,函数增加了kernel关键字,它声明该函数是:

  • 公共的GPU函数(public GPU function)。公共函数是你的应用程序中唯一能看到的函数。公共函数不能被其他着色器函数调用。
  • 计算型函数(compute function)(也称为计算型内核),它使用线程网格(grid of threads)进行并行计算。

参阅《Using a Render Pipeline to Render Primitives》,了解用于声明公共图形函数的其他函数关键字。

add_arrays函数用device关键字声明了它的三个参数,表示这些指针在device地址空间。MSL为内存定义了几个相互隔离的地址空间。每当在MSL中声明一个指针时,必须提供一个关键字来声明它的地址空间。使用device地址空间,表示这是一块GPU可以读写的持久性内存。

清单2删除了清单1中的for循环,因为该函数现在被计算网格中的多个线程调用。示例创建了一个与数组大小完全匹配的一维线程网格,因此数组中的每一项都由不同的线程计算。

为了替换之前由for循环提供的索引,函数增加一个新的index参数,并使用C++属性语法指定另一个MSL关键字,thread_position_in_grid。这个关键字声明了Metal应该为每个线程计算一个唯一的索引,并通过该参数传递该索引。因为add_arrays使用的是一维网格,所以索引被定义为一个标量整数(scalar integer)。即使删除了循环,清单1和清单2还是使用相同的代码将两个数字相加。如果你想把类似的代码从C或C++转换称MSL,请用同样的方法把循环逻辑替换成网格形式。

获取GPU

在程序中,MTLDevice对象是一个GPU的精简抽象,你可以用它来与GPU通信。Metal为每个GPU创建了一个MTLDevice对象。通过调用MTLCreateSystemDefaultDevice获得默认的设备对象。在macOS中,一个Mac可以有多个GPU,Metal选择其中一个作为默认值,并返回该GPU的设备对象。在macOS中,Metal还提供了其他的API,可以用它独立检索所有的设备对象,但本示例只是使用默认的设备对象。

id<MTLDevice> device = MTLCreateSystemDefaultDevice();

初始化Metal对象

Metal将其他GPU相关的实体都表示为对象,如已编译的着色器、内存缓冲区和纹理。要创建这些GPU特定对象,可以调用MTLDevice的对应的类方法或对象方法。一个设备对象只能使用由其自身直接或间接创建的实体对象。使用多个GPU的应用程序将使用多个设备对象,并为每个设备对象创建类似的Metal对象层次结构。

示例程序使用一个自定义的MetalAdder类来管理需要与GPU通信的对象。该类的构造器创建了这些对象,并将其存储在其属性中。程序创建该类的一个实例,传入Metal设备对象,用于创建辅助对象。MetalAdder对象保持对Metal对象的强引用,直到它执行完毕。

MetalAdder* adder = [[MetalAdder alloc] initWithDevice:device];

在Metal,类似这样的昂贵的构造任务可以一次执行,然后重用其结果。你很少需要在性能敏感的代码中运行这样的任务。

获取Metal函数的引用

构造器做的第一件事是加载函数, 并准备在GPU上运行。当在构建程序时,Xcode会编译add_arrays函数,将其添加到一个默认的Metal库中,并嵌入到程序包中。可以使用MTLLibraryMTLFunction对象来获取Metal库和其中包含的函数信息。要获得add_arrays函数,调用MTLDevice为默认库创建一个MTLLibrary对象,然后向库获取代表着色器函数的MTLFunction对象。

- (instancetype) initWithDevice: (id<MTLDevice>) device {     self = [super init];     if (self)     {         _mDevice = device;          NSError* error = nil;          // Load the shader files with a .metal file extension in the project          id<MTLLibrary> defaultLibrary = [_mDevice newDefaultLibrary];         if (defaultLibrary == nil)         {             NSLog(@"Failed to find the default library.");             return nil;         }          id<MTLFunction> addFunction = [defaultLibrary newFunctionWithName:@"add_arrays"];         if (addFunction == nil)         {             NSLog(@"Failed to find the adder function.");             return nil;         }

准备Metal管线

该函数对象是MSL函数的代理,但它不是可执行的代码。你可以通过创建一个管线(pipeline)把函数转换成可执行的代码。一个管线指定了GPU为完成一个特定任务而执行的步骤。在Metal中,一个管线由一个管线状态对象(pipeline state object)表示。因为这个示例使用了一个计算型函数,所以程序对应地创建了一个MTLComputePipelineState对象。

_mAddFunctionPSO = [_mDevice newComputePipelineStateWithFunction: addFunction error:&error];

一个计算型管线运行一个计算型函数,在运行函数之前可以选择对输入数据进行操作,在运行函数之后对输出数据进行操作。

当你创建一个管线状态对象时,设备对象会完成对这个特定GPU的函数编译。本示例同步创建了管线状态对象,并直接返回给应用程序。因为编译确实需要一定时间,所以避免在性能敏感的代码中同步创建管线状态对象。

注意

在目前给出的代码中,Metal返回的所有对象都是作为遵守协议的对象返回的。Metal用协议定义了大多数GPU特定的对象,以抽象出底层的实现类,这其具体实现可能会因不同的GPU而有所不同。Metal使用类定义与GPU无关的对象。任何一个给定的Metal协议的参考文档都会明确你是否可以在你的应用中实现该协议。

创建命令队列

要向GPU发送命令,你需要一个命令队列。Metal使用命令队列来调度命令。用MTLDevice创建一个命令对象。

_mCommandQueue = [_mDevice newCommandQueue];

创建数据缓冲区并加载数据

在初始化基本的Metal对象后,要为GPU加载数据来执行着色器程序。这个任务对性能的要求不高,但在程序启动初期来完成该操作还是很有帮助的。

GPU可以有自己专用的内存,也可以与操作系统共享内存。当你把数据存储在内存,并让数据在GPU可用时,Metal和操作系统内核需要执行额外的工作。Metal使用资源对象(MTLResource)抽象了这种内存管理。资源是GPU在运行命令时可以访问的已分配内存。使用MTLDevice为GPU创建资源。

示例程序创建了三个缓冲区,并在前两个缓冲区中填充随机数据。第三个缓冲区是add_arrays存储其结果的地方。

“`
_mBufferA = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared];
_mBufferB = [_mDevice newBufferWithLength:bufferSize options:MTLResourceStorageModeShared];

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 在GPU上执行计算求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们