1

是否有可能从以下简单类中获得 3-6 倍的加速?

我正在尝试创建一个伪装成内联函数的类,但括号/subsref 运算符重载对我来说速度不够快。

我创建了一个类CTestOp来替换内联函数 ,方法f = @(x) A*x是让 subsref 获取一个向量并将其与类属性相乘A

基准测试表明,对于小尺寸Ax(例如,m = 5),使用内联函数需要 4-7 倍的时间,因为使用内联函数A*x需要 4-7 倍的时间来使用类使用内联函数:

Elapsed time is 0.327328 seconds for the class
Elapsed time is 0.053322 seconds for the inline function.
Elapsed time is 0.011704 seconds for just writing A*x.

我已经进行了一系列改进才能到达这里,但存在问题。例如,我可以看到实质性的收获,不要求this.A但随后违背了整个目的。我本来希望使用一个允许我们编写各种operation函数的抽象类——但是,虽然使类抽象并没有增加太多时间,但使实际的函数调用却增加了时间。

有任何想法吗?

课程是:

classdef CTestOp < handle

    properties     
        A = [];
    end

    methods
        function this = CTestOp(A)
            this.A = A;
        end

        function result = operation(this, x)
            result = this.A*x;
        end

        function result = subsref(this, S)

%             switch S.type
%                 case '()'
                    %   result = this.operation(S.subs{1});  % Killed because this was really slow
                    %   result = operation(this, S.subs{1}); % I wanted this, but it was too slow
                    result = this.A*S.subs{1};
%                 otherwise
%                     result = builtin('subsref', this, S);
%             end

        end
    end

end

虽然测试代码是:

m = 5;
A = randn(m,m);
x = randn(m,1);

f = @(x) A*x;

myOp = CTestOp(A);

nc = 10000;

% Try with the class:
tic
for ind  = 1:nc
r_abs = myOp(x);
end
toc


% Try with the inline function:
tic
for ind = 1:nc
r_fp = f(x);
end
toc

% Try just inline. so fast!
tic
for ind = 1:nc
r_inline = A*x;
end
toc
4

1 回答 1

1

如果您想在 Matlab 中编写快速代码,诀窍始终是对代码进行矢量化。使用 Matlab OO 也是如此。虽然我目前无法对其进行测试,但我非常有信心您可以通过执行一项大操作而不是许多小操作来减少开销。

在您的具体示例中,您可以再次运行基准测试,并通过更改这两行来查看我的声明是否真的成立:

m = 500; % Work with one big matrix rather than many tiny ones

nc = 99; % Just some number that should give you reasonable run times
于 2013-02-05T14:43:03.050 回答