[arrays] arrayfun peut être significativement plus lent qu'une boucle explicite dans matlab. Pourquoi?


Answers

C'est parce que !!!!

x = randn(T, N); 

n'est pas de type gpuarray ;

Tout ce que vous devez faire est

x = randn(T, N,'gpuArray');
Question

Considérez le test de vitesse simple suivant pour arrayfun :

T = 4000;
N = 500;
x = randn(T, N);
Func1 = @(a) (3*a^2 + 2*a - 1);

tic
Soln1 = ones(T, N);
for t = 1:T
    for n = 1:N
        Soln1(t, n) = Func1(x(t, n));
    end
end
toc

tic
Soln2 = arrayfun(Func1, x);
toc

Sur ma machine (Matlab 2011b sur Linux Mint 12), la sortie de ce test est:

Elapsed time is 1.020689 seconds.
Elapsed time is 9.248388 seconds.

Qu'est-ce que le?!? arrayfun , tout en admettant une solution plus propre, est un ordre de grandeur plus lent. Qu'est-ce qui se passe ici?

En outre, j'ai fait un test similaire pour cellfun et trouvé qu'il était environ 3 fois plus lent qu'une boucle explicite. Encore une fois, ce résultat est le contraire de ce à quoi je m'attendais.

Ma question est: Pourquoi arrayfun et cellfun sont- cellfun tellement plus lents? Et étant donné cela, y a-t-il de bonnes raisons de les utiliser (autre que de rendre le code bien paraître)?

Note: Je parle ici de la version standard de arrayfun , PAS de la version GPU de la boîte à outils de traitement parallèle.

EDIT: Juste pour être clair, je suis conscient que Func1 ci-dessus peut être vectorisé comme indiqué par Oli. Je ne l'ai choisi que parce qu'il donne un simple test de vitesse aux fins de la question.

EDIT: Suite à la suggestion de grungetta, j'ai refait le test avec la feature accel off . Les résultats sont:

Elapsed time is 28.183422 seconds.
Elapsed time is 23.525251 seconds.

En d'autres termes, il semblerait qu'une grande partie de la différence est que l'accélérateur JIT fait un bien meilleur travail d'accélération de la boucle for explicite que celle de arrayfun . Cela me semble étrange puisque arrayfun fournit plus d'informations, c'est-à-dire que son utilisation révèle que l'ordre des appels à Func1 pas d'importance. Aussi, j'ai noté que si l'accélérateur JIT est allumé ou éteint, mon système n'utilise jamais qu'un processeur ...




Links