2017-10-05 1 views
0

私はthis postを読んで、ジュリアではループがより速いことに気付きました。したがって、私はベクトル化されたコードをループに変更することに決めました。しかし、私はループ内でいくつかのif文を使用しなければならなかったが、if文を追加するとループが遅くなった。私のループは遅いです。それはif文のためですか?

function devectorized() 
    a = [1.0, 1.0] 
    b = [2.0, 2.0] 
    x = [NaN, NaN] 

    for i in 1:1000000 
     for index in 1:2 
      x[index] = a[index] + b[index] 
     end 
    end 

    return 
end 

function time(N) 
    timings = Array(Float64, N) 

    # Force compilation 
    devectorized() 

    for itr in 1:N 
     timings[itr] = @elapsed devectorized() 
    end 

    return timings 
end 

文が速度をテストする場合、私は、数を追加しました::

function devectorized2() 
    a = [1.0, 1.0] 
    b = [2.0, 2.0] 
    x = [NaN, NaN] 

    for i in 1:1000000 
     for index in 1:2 

      ####repeat this 6 times 
      if index * i < 20 
       x[index] = a[index] - b[index] 
      else 
       x[index] = a[index] + b[index] 
      end 
      #### 

     end 
    end 

    return 
end 

私はこのブロックを6回繰り返した:

は、この私が直接ポストからコピー抜粋、考えてみましょう

  if index * i < 20 
       x[index] = a[index] - b[index] 
      else 
       x[index] = a[index] + b[index] 
      end 

簡潔にするために、サンプルコードでこのブロックを繰り返しません。 if文を6回繰り返した後、devectorized2()は3倍の時間がかかりました。

私は2つの質問があります。

  1. がif文を実装するためのより良い方法はありますか?
  2. if文が遅いのはなぜですか?私はJuliaがCと一致する方法でループを実行しようとしていることを知っています。JuliaはJuliaとCの間のより良い "翻訳"を提供しています。
+0

ループの内側部分を6回繰り返したところ、6倍でなく3倍の速度しか落としませんでしたか?それは私にはうってつけです...あなたが正しく読めば、仕事の量は約6倍になるはずです。これはおそらく、分岐予測のために6x未満です。 –

+0

どうすればいいですか? – tryingtosolve

+1

加算回数を6倍にすると、演算回数の6倍を必要とするため、加算回数が6倍になります。あなたはそれについて何もできません。それはどんな言語でも真実です。それをCまたはFortranで試してみてください。 –

答えて

2

第1に、私はあなたの機能に多くの作業を追加しているので、ここでのパフォーマンスは非常に奇妙ではないと思います。

第2に、実際にはreturn xここで、そうでなければ、コンパイラはxを使用していないと判断し、タイミングを完全に混乱させる計算全体をスキップするだけです。

第三に、あなたの質問1に答えるために:あなたはこのようにそれを実装することができます

x[index] = a[index] + ifelse(index * i < 20, -1, 1) * b[index] 

これは、いくつかのケースでは、必ずしも必要ではないが、分岐を予測するのは非常に簡単です、あなたの場合、中に高速になります。時には、あなたもこのように、たとえば、Bool Sを使用してスピードアップを取得することができます:

x[index] = a[index] + (2*(index * i >= 20)-1) * b[index] 

ここでも、あなたの例では、これはあまり役に立ちませんが、このアプローチは、あなたにまともなスピードアップを与えることができる場合があります。

BTW:これ以上ベクトル化されたコードよりもループが望ましいとは限りません。リンク先の投稿はかなり古いです。 this blog postを見てください。これは、ベクトル化されたコードが偽のコードと同様のパフォーマンスを達成する方法を示しています。しかし、多くの場合、目標を達成するためにループが最も明瞭で、最も簡単で最速の方法です。

関連する問題