比较BSXFUN和REPMAT比较BSXFUN和REPMAT(Comparing BSXFUN an

2019-05-10 11:41发布

几个问题是对之间的比较之前问bsxfunrepmat性能。

  • 其中之一是: Matlab - bsxfun no longer faster than repmat? 。 这一次试图调查之间的性能比较repmatbsxfun ,具体到沿从输入数组本身,因此列进行输入数组的平均值的减法将探索只有@minus的一部分bsxfun针对其repmat等同。
  • 另一个问题是: In Matlab, when is it optimal to use bsxfun? 。 那一个试图通过平均沿着列做减法的相同的操作,并没有扩展到其他内置操作要么。

有了这个帖子,我想探讨的性能数字bsxfunrepmat覆盖所有bsxfun内置插件来排序的给它一个更宽的视角,这些都呈现良好矢量化的解决方案。

具体来说,我的问题与这个职位是:

  1. 如何与各种内置的操作bsxfun执行对repmat等价物? bsxfun支持浮点运算像@plus@minus@times等,也如关系和逻辑运算@ge@and等,所以,有没有具体的内置插件,会给我明显的加速与bsxfun比使用他们repmat等价物?

  2. 罗兰在她的blog post已经基准repmatbsxfun带定时@() A - repmat(mean(A),size(A,1),1)@() bsxfun(@minus,A,mean(A))分别为。 如果我需要涵盖基准所有内置插件,我可以使用一些其他的比较模式,将与浮点,关系和逻辑运算工作?

Answer 1:

介绍

是否辩论bsxfun优于repmat反之亦然已经持续了像永远。 在这篇文章中,我们会尝试比较不同的内置插件与MATLAB船怎么打出来反对repmat在它们的运行时性能方面等同,希望得出一些有意义的结论了出来。

结识BSXFUN内置插件

如果官方文件从MATLAB环境,或通过拉出Mathworks公司的网站 ,可以看到由支持的内置函数的完整列表bsxfun 。 这份名单有浮点,关系和逻辑运算功能。

MATLAB 2015A ,支持逐元素的浮点运算是:

  • @plus(求和)
  • @minus(减法)
  • @times(乘法)
  • @rdivide(右分)
  • @ldivide(左分)
  • @pow(功率)
  • @rem(余数)
  • @mod(模数)
  • @ ATAN2(四个象限反正切)
  • @ atan2d(以度为单位的四象限反正切)
  • @hypot(平方和的平方根)。

第二组由逐元素关系操作的那些是:

  • @eq(相等)
  • @ne(不等于)
  • @lt(小于)
  • @le(小于或等于)
  • @gt(大于)
  • @ge(大于或等于)。

逻辑运算的第三和最后一组包括如下所列:

  • @and(逻辑和)
  • @or(逻辑或)
  • @xor(逻辑异或)。

请注意,我们已经排除了两个内置插件@max (maximum)@min (minimum)从我们的对比测试中,因为可能有很多方法可以实现他们的repmat等价物。

比较型号

要真正比较的表演repmatbsxfun ,我们需要确保时序只需要覆盖预期的操作。 因此,像bsxfun(@minus,A,mean(A))将不理想,因为它具有计算mean(A)这里面bsxfun通话,但是无意义的,时间上可能。 取而代之的是,我们可以使用另一输入B相同大小的mean(A)

因此,我们可以使用: A = rand(m,n) B = rand(1,n)其中, mn是大小参数,我们可以改变和研究基于它们的性能。 这将在下一节中列出了基准测试准确完成。

repmatbsxfun版本这些输入操作会看起来像这些-

REPMAT: A + repmat(B,size(A,1),1)
BSXFUN: bsxfun(@plus,A,B)

标杆

最后,我们在这篇文章看这两个家伙打出来的症结所在。 我们已经分开了标杆成三组,一个用于浮点操作,另一个用于关系,第三个用于逻辑运算。 我们延长了比较模型早些时候所有的这些操作进行讨论。

SET1:浮点运算

这里的第一套基准的浮点运算用代码的repmatbsxfun -

datasizes = [ 100 100; 100 1000; 100 10000; 100 100000;
              1000 100; 1000 1000; 1000 10000;
              10000 100; 10000 1000; 10000 10000;
              100000 100; 100000 1000];

num_funcs = 11;
tsec_rep = NaN(size(datasizes,1),num_funcs);
tsec_bsx = NaN(size(datasizes,1),num_funcs);
for iter = 1:size(datasizes,1)
    m = datasizes(iter,1);
    n = datasizes(iter,2);
    A = rand(m,n);
    B = rand(1,n);

    fcns_rep= {@() A + repmat(B,size(A,1),1),@() A - repmat(B,size(A,1),1),...
        @() A .* repmat(B,size(A,1),1), @() A ./ repmat(B,size(A,1),1),...
        @() A.\repmat(B,size(A,1),1), @() A .^ repmat(B,size(A,1),1),...
        @() rem(A ,repmat(B,size(A,1),1)), @() mod(A,repmat(B,size(A,1),1)),...
        @() atan2(A,repmat(B,size(A,1),1)),@() atan2d(A,repmat(B,size(A,1),1)),...
        @() hypot( A , repmat(B,size(A,1),1) )};

    fcns_bsx = {@() bsxfun(@plus,A,B), @() bsxfun(@minus,A,B), ...
        @() bsxfun(@times,A,B),@() bsxfun(@rdivide,A,B),...
        @() bsxfun(@ldivide,A,B), @() bsxfun(@power,A,B), ...
        @() bsxfun(@rem,A,B), @() bsxfun(@mod,A,B), @() bsxfun(@atan2,A,B),...
        @() bsxfun(@atan2d,A,B), @() bsxfun(@hypot,A,B)};

    for k1 = 1:numel(fcns_bsx)
        tsec_rep(iter,k1) = timeit(fcns_rep{k1});
        tsec_bsx(iter,k1) = timeit(fcns_bsx{k1});
    end
end
speedups = tsec_rep./tsec_bsx;

SET2:关系运算

该基准测试代码,以时间关系操作将取代fcns_repfcns_bsx与这些同行前面的基准测试代码-

fcns_rep = {
    @() A == repmat(B,size(A,1),1), @() A ~= repmat(B,size(A,1),1),...
    @() A < repmat(B,size(A,1),1), @() A <= repmat(B,size(A,1),1), ...
    @() A > repmat(B,size(A,1),1), @() A >= repmat(B,size(A,1),1)};

fcns_bsx = {
    @() bsxfun(@eq,A,B), @() bsxfun(@ne,A,B), @() bsxfun(@lt,A,B),...
    @() bsxfun(@le,A,B), @() bsxfun(@gt,A,B), @() bsxfun(@ge,A,B)};

SET3:逻辑运算

最后一组标杆代码将使用逻辑运算此处所列的 -

fcns_rep = {
    @() A & repmat(B,size(A,1),1), @() A | repmat(B,size(A,1),1), ...
    @() xor(A,repmat(B,size(A,1),1))};

fcns_bsx = {
    @() bsxfun(@and,A,B), @() bsxfun(@or,A,B), @() bsxfun(@xor,A,B)};

请注意,对于该特定组,输入数据,A和B分别为所需的逻辑阵列。 所以,我们在前面的基准测试代码来创建逻辑阵列做这些编辑 -

A = rand(m,n)>0.5;
B = rand(1,n)>0.5;

运行时和观察

该基准测试代码已在此系统配置运行:

MATLAB Version: 8.5.0.197613 (R2015a)
Operating System: Windows 7 Professional 64-bit
RAM: 16GB
CPU Model: Intel® Core i7-4790K @4.00GHz

因此与获得的加速比bsxfun超过repmat运行基准测试之后绘制的三组如下所示。

A.浮点运算:

一些看法可以从加速曲线图可以得出:

  • 该特别是两个很好的加速比例bsxfunatan2atan2d
  • 其次在该列表是提升执行与左,右除法运算30% - 50%以上的repmat等价代码。
  • 要在该列表中进一步下跌的其余7操作,其速度提升似乎非常接近统一,因此需要进一步的检查。 在加速的情节可以被缩小到只是那些7如下图所示的操作-

基于上述情节,人们可以看到,禁止一次性例@hypot@modbsxfun仍然表现优于10%左右repmat这些7操作。

B.关系运算:

这是由内置支持的关系运算未来6第二套标杆bsxfun

在加速的情节看上面,而忽略了那间可比的运行时间开始的情况下bsxfunrepmat ,人们可以很容易地看到bsxfun赢得了这些关系操作。 随着接触的加速10xbsxfun将永远是最好的这些情况。

C.逻辑操作:

这是第三套为基准所支持的其余3个内置的逻辑运算的bsxfun

忽视了对一次性可比的运行情况@xor在一开始, bsxfun似乎有占上风这组逻辑操作了。

结论

  1. 当使用关系和逻辑运算工作, repmat可以很容易地有利于遗忘bsxfun 。 对于的情况下休息,一个仍然可以坚持bsxfun如果一次性例, 5 - 7%较低性能是可以容忍的。
  2. 使用带有关系和逻辑操作时,看到的那种巨大的性能提升的bsxfun ,可以考虑使用bsxfun对处理数据ragged patterns ,类似的性能优势电池阵列。 我喜欢把这些解决案件使用那些bsxfun的屏蔽能力 。 这基本上意味着,我们创建逻辑阵列,即口罩bsxfun ,其可以被用于交换单元阵列和数字阵列之间的数据。 的优点之一为具有数字数组可行数据是量化方法可以被用来处理它们。 同样,由于bsxfun是矢量一个很好的工具,你会发现自己使用它再次在同一个问题的工作下来,所以有更多的理由去了解bsxfun 。 少数溶液的情况下,我能够探索这样的方法是此处链接为读者的利益: 1 , 2 , 3 , 4 , 5 。

未来的工作

目前的工作重点是随着一名维复制数据repmat 。 现在, repmat可以沿着多个维度复制等做bsxfun其扩张等同于重复。 因此,这将是有趣执行上复制并展开的类似试验在多个维度与这两个功能。



文章来源: Comparing BSXFUN and REPMAT