MPSMatrixVectorMultiplication слишком медленный - PullRequest
0 голосов
/ 06 ноября 2019

Я работаю над алгоритмом графического процессора, который выполняет сложные математические вычисления, в основном связанные с матрицами и векторами. Хотя у меня хорошие показатели с точки зрения времени обработки, я все еще чувствую, что есть место для улучшений.

Так что я открыл для себя Metal Performance Shaders framework. Описание этого фреймворка взволновало меня, потому что я могу найти точно настроенные и оптимизированные шейдеры ядра для математических операций, которые выполняет мой алгоритм GPU.

Я решил сначала использовать MPSMatrixVectorMultiplication, потому что у меня большое умножение 11000x500 матрица на 11000 vector с выводом 500 вектора.

Так вот, как я это использую. Объявите MPS оболочки для MTLBuffer s и саму операцию:

MPSMatrix *model;
MPSVector *vector;

id<MTLBuffer> resultBuffer;
MPSVector *resultVector;
MPSMatrixVectorMultiplication *matrixVectorMultiplication;

Инициализируйте эти MPS оболочки:

matrixVectorMultiplication = [[MPSMatrixVectorMultiplication alloc] initWithDevice:_ctx.device transpose:true rows:500 columns:11000 alpha:1 beta:0];

//......//

MPSVectorDescriptor *desc = [MPSVectorDescriptor vectorDescriptorWithLength:11000 dataType:MPSDataTypeFloat32];
vector = [[MPSVector alloc] initWithBuffer:vecBuffer descriptor:desc];

MPSVectorDescriptor *desc_out = [MPSVectorDescriptor vectorDescriptorWithLength:500 dataType:MPSDataTypeFloat32];
resultVector = [[MPSVector alloc] initWithBuffer:resultBuffer descriptor:desc_out];

//......//

MPSMatrixDescriptor *desc = [MPSMatrixDescriptor matrixDescriptorWithRows:11000 columns:500 rowBytes:500 * sizeof(float) dataType:MPSDataTypeFloat32];  //I need to transpose the matrix     
model = [[MPSMatrix alloc] initWithBuffer:testBuffer descriptor:desc];

И сделайте умножение:

id<MTLCommandBuffer> cmdBuffer = [_ctx.commandQueue commandBuffer];
id<MTLComputeCommandEncoder> encoder = [cmdBuffer computeCommandEncoder];

// work with my own encoder, execute some commands

[encoder endEncoding];

[matrixVectorMultiplication encodeToCommandBuffer:cmdBuffer inputMatrix:model inputVector:vector resultVector:resultVector];

[cmdBuffer commit];
[cmdBuffer waitUntilCompleted]; // I have to wait because my algorithm is sequential at this point

Теперь функция ядра, которую я написал, выполняет точно такое же умножение примерно за 0.8-1.1 мс. И мне было очень грустно узнать, что MPSMatrixVectorMultiplication сделал это за 18-19 ms!

Это слишком медленно, и я не могу поверить в такой результат. Понятно, что мне не хватает какой-то крошечной детали, которая сильно влияет на производительность.

Есть ли кто-нибудь, кто использовал решения MPS в чувствительном к производительности коде? Я был бы рад услышать несколько советов, которые я могу применить в своей рутине GPU.

Заранее спасибо!

...