【问题标题】:Objective C - Matrix Multiplication Slow PerformanceObjective C - 矩阵乘法性能缓慢
【发布时间】:2012-05-22 05:07:58
【问题描述】:

我有 2 个二维 NSMutableArrays,我正在尝试做一些基本的矩阵乘法。我在下面有我的通用公式代码,但它的性能非常慢(正如预期的那样)。我做了很多谷歌搜索,但没有找到任何简单或易于理解的公式来更改代码以提高性能。谁能指出一个简单的公式/教程/示例的正确方向,说明如何在 Objective C 中使用矩阵乘法获得比 0(n^3) 更好的性能。

+ (NSMutableArray*)multiply:(NSMutableArray*)a1 withArray:(NSMutableArray*)a2
{
    if([[a1 objectAtIndex: 0] count] != [a2 count])
    {
        NSLog(@"Multiplicaton error!");
        return NULL;
    }

    int a1_rowNum = [a1 count];
    int a2_rowNum = [a2 count];
    int a2_colNum = [[a2 objectAtIndex:0] count];
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:a1_rowNum];
    for (int i = 0; i < a1_rowNum; i++) {
        NSMutableArray *tempRow = [NSMutableArray arrayWithCapacity:a2_colNum];
        for (int j = 0; j < a2_colNum; j++) {
            double tempTotal = 0;
            for (int k = 0; k < a2_rowNum; k++) {
                double temp1 = [[[a1 objectAtIndex:i] objectAtIndex:k] doubleValue];
                double temp2 = [[[a2 objectAtIndex:k] objectAtIndex:j] doubleValue];
                tempTotal += temp1 * temp2;
            }
             //Stored as a string because I upload it to an online database for storage.
            [tempRow addObject:[NSString stringWithFormat:@"%f",tempTotal]];
        }
        [result addObject:tempRow];
    }
    return result;
}

【问题讨论】:

  • 您是否测试过 C 版本是否会更好?这两个矩阵有多大(维度)?
  • 阵列约为 50-200 x 50-200。

标签: objective-c matrix nsmutablearray multiplication matrix-multiplication


【解决方案1】:

如果你用C写会快很多。


double[]NSArrayNSNumbers 相比将快得离谱。您将拥有良好的缓存一致性、最少的指令,无需通过运行时或分配来写入或读取元素。无需对每个元素执行引用计数循环……

【讨论】:

  • 有没有一种简单的方法可以用 C 语言编写它?我的问题是除了学习目标 C 之外,我只知道 Java,而且我找不到将 double[][] 作为参数传递给方法的“消息”的方法。
  • @MrHappyAsthma 在这种情况下,您可以考虑创建一个 objc 类来保存您的多维数组。当然,您会希望避免对该数组的任何/每次读/写都使用 objc 消息传递。同样,double 可能比您需要的更准确——考虑float。如果你不需要引用计数,你也可以把它放在一个结构中。
  • Objective-C 是 C 的超集。要在 Objective-C 中编写 C,您实际上就是这样做的。
  • @WilburVandrsmith:Objective C 仅是 C 语言,但是当我们向 NSMutableArray 对象发送 objectAtIndex、addObject 消息时,我们会在运行时进行额外的计算。其中包括查找 isa 指针,了解消息选择器,然后转到相应的函数。每次都会发生这种情况,如果数组 id 说 100 x 100 它会在处理过程中造成损失。
  • 要么完全用 C 语言编写它,要么使用 Objective C 的运行时方法来优化此代码将是另一种选择。有一些运行时方法可以为类的选择器提供实际的 C 函数,可以避免在运行时进行不必要的查找。但是,当您拥有 Apple 本身强大的优化库时,为什么还要自己发明一些东西。此外,一旦你学会了如何使用它,它在以后总是有用的。
【解决方案2】:

您需要查看 Apple 的 Accelerate 框架,适用于 ios4.0 及以上。 你可以用它做很多复杂的数学和矩阵操作,而且这个框架经过优化,可以在任何 iOS 硬件上运行。

结帐:

https://developer.apple.com/performance/accelerateframework.html

【讨论】:

  • 特别是,cblas_dgemm 函数看起来正是您要寻找的。或者 cblas_sgemm 如果您只需要单精度。
猜你喜欢
  • 2013-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-28
  • 2018-03-24
  • 2015-02-03
  • 2020-06-12
  • 2021-08-04
相关资源
最近更新 更多