阵列火灾评估方程运行非常缓慢

时间:2015-04-09 16:43:43

标签: gpgpu arrayfire

我一直致力于使用arrayfire模拟生物启发的神经网络的项目。我做了一些时间测试,并对我得到的结果感到失望。我决定尝试使用最快,最简单的模型之一进行定时测试,即Izhikevich模型。当我使用该模型运行新测试时,结果更糟。我正在使用的代码如下。它没有做任何花哨的事情。它只是标准矩阵代数。但是,仅对10个神经元进行单一的等式评估需要5秒钟!之后的每一站都需要大致相同的时间。

代码:

unsigned int neuron_count = 10;

array a = af::constant(0.02, neuron_count);
array b = af::constant(0.2, neuron_count);
array c = af::constant(-65.0, neuron_count);
array d = af::constant(6, neuron_count);

array v = af::constant(-70.0, neuron_count);
array u = af::constant(-20.0, neuron_count);
array i = af::constant(14, neuron_count);

double tau = 0.2;

void StepIzhikevich()
{
    v = v + tau*(0.04*pow(v, 2) + 5 * v + 140 - u + i);
    //af_print(v);
    u = u + tau*a*(b*v - u);
    //Leaving off spike threshold checks for now
}

void TestIzhikevich()
{
    StepIzhikevich();

    timer::start();

    StepIzhikevich();

    printf("elapsed seconds: %g\n", timer::stop());
}

以下是不同数量神经元的计时结果。

结果:

neurons   seconds
10        5.18275
100       5.27969
1000      5.20637
10000     4.86609

增加神经元的数量似乎没有产生巨大影响。时间有点下降了。我在这里做错了吗?有没有更好的方法来使用arrayfire优化事物以获得更好的结果?

当我将v方程切换为使用v * v而不是pow(v,2)时,步骤所需的时间降至3.75762。但这仍然非常缓慢,所以发生了一些奇怪的事情。

[编辑] 我试图将处理拆分成碎片并找到新的东西。这是我现在使用的代码。

代码:

unsigned int neuron_count = 10;

array a = af::constant(0.02, neuron_count);
array b = af::constant(0.2, neuron_count);
array c = af::constant(-65.0, neuron_count);
array d = af::constant(6, neuron_count);

array v = af::constant(-70.0, neuron_count);
array u = af::constant(-20.0, neuron_count);
array i = af::constant(14, neuron_count);

array g = af::constant(0.0, neuron_count);

double tau = 0.2;

void StepIzhikevich()
{
    array j = tau*(0.04*pow(v, 2));
    //af_print(j);

    array k = 5 * v + 140 - u + i;
    //af_print(k);

    array l = v + j + k;
    //af_print(l);

    v = l;  //If this line is here time is long on second loop
    //g = l; //If this is here then time is short.

    //u = u + tau*a*(b*v - u);
    //Leaving off spike threshold checks for now
}

void TestIzhikevich()
{
    timer::start();

    StepIzhikevich();

    printf("elapsed seconds: %g\n", timer::stop());

    timer::start();

    StepIzhikevich();

    printf("elapsed seconds: %g\n", timer::stop());
}

当我在没有重新分配回v的情况下运行它或将其分配给新变量g时,第一次和第二次运行的步骤时间都很小

结果:

经过秒数:0.0036143

经过秒:0.00340621

然而,当我把v = l;回来,然后第一次运行它很快,但从那时起它很慢。

结果:

经过秒数:0.0034497

经过秒:2.98624

关于导致这种情况的任何想法?

[编辑2]

我仍然不知道为什么会这样做,但是我通过在再次使用之前复制v阵列找到了一种解决方法。

代码:

unsigned int neuron_count = 100000;

array v = af::constant(-70.0, neuron_count);
array u = af::constant(-20.0, neuron_count);
array i = af::constant(14, neuron_count);

double tau = 0.2;

void StepIzhikevich()
{
    //array vp = v;
    array vp = v.copy();
    //af_print(vp);

    array j = tau*(0.04*pow(vp, 2));
    //af_print(j);

    array k = 5 * vp + 140 - u + i;
    //af_print(k);

    array l = vp + j + k;
    //af_print(l);

    v = l;  //If this line is here time is long on second loop
}

void TestIzhikevich()
{
    for (int i = 0; i < 10; i++)
    {
        timer::start();

        StepIzhikevich();

        printf("loop: %d  ", i);
        printf("elapsed seconds: %g\n", timer::stop());

        timer::start();
    }
}

现在结果如下。它第二次运行它有点慢,但现在它很快。比以前有了巨大的进步。

结果: loop:0经过秒:0.657355

循环:1秒过去:0.981287

循环:2秒过去:0.000416182

循环:3秒过去:0.000415045

循环:经过4秒:0.000421014

循环:经过5秒:0.000413339

循环:经过6秒:0.00041675

循环:7秒过去:0.000412202

循环:8秒过去:0.000473321

循环:9秒过去:0.000677432

0 个答案:

没有答案