タグ付けされた質問 「compiler-optimization」

コンパイラーの最適化には、ランタイムまたはオブジェクトのサイズ、あるいはその両方を削減するようにコンパイラーを調整することが含まれます。これは、コンパイラー引数(CFLAGS、LDFLAGSなど)、コンパイラープラグイン(DEHYDRAなど)、またはコンパイラーへの直接変更(ソースコードの変更など)を使用して実行できます。

10
要素ごとの加算が、結合されたループよりも個別のループではるかに速いのはなぜですか?
仮定a1、b1、c1、およびd1ヒープメモリと私の数値コードのポイントは、以下のコアループを有しています。 const int n = 100000; for (int j = 0; j < n; j++) { a1[j] += b1[j]; c1[j] += d1[j]; } このループは、別の外部forループを介して10,000回実行されます。スピードアップするために、コードを次のように変更しました。 for (int j = 0; j < n; j++) { a1[j] += b1[j]; } for (int j = 0; j < n; j++) { c1[j] += …

12
GCCがa * a * a * a * a * aを(a * a * a)*(a * a * a)に最適化しないのはなぜですか?
科学的なアプリケーションで数値の最適化を行っています。私が気づいたことの1つは、GCCはにpow(a,2)コンパイルすることで呼び出しを最適化しますa*aが、呼び出しpow(a,6)は最適化されておらず、実際にはライブラリ関数を呼び出すpowため、パフォーマンスが大幅に低下します。(対照的に、インテルC ++コンパイラー(実行可能icc)は、のライブラリー呼び出しを排除しますpow(a,6)。) 私は好奇心だと、私は交換したときにということであるpow(a,6)とa*a*a*a*a*aGCC 4.5.1とオプション「を使用して-O3 -lm -funroll-loops -msse4」、それは5つの使用mulsd説明書を: movapd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 私が書いた場合(a*a*a)*(a*a*a)、それは生成されます movapd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm14, %xmm13 mulsd %xmm13, %xmm13 乗算命令の数を3に減らすと、icc同様の動作になります。 コンパイラがこの最適化トリックを認識しないのはなぜですか?

10
32ビットのループカウンターを64ビットで置き換えると、Intel CPUで_mm_popcnt_u64を使用すると、パフォーマンスが大幅にずれる
popcount大規模なデータ配列への最速の方法を探していました。私が遭遇した非常に奇妙な効果を:からループ変数を変更するunsignedにuint64_t私のPC上で50%で作られたパフォーマンスの低下を。 ベンチマーク #include <iostream> #include <chrono> #include <x86intrin.h> int main(int argc, char* argv[]) { using namespace std; if (argc != 2) { cerr << "usage: array_size in MB" << endl; return -1; } uint64_t size = atol(argv[1])<<20; uint64_t* buffer = new uint64_t[size/8]; char* charbuffer = reinterpret_cast<char*>(buffer); for (unsigned i=0; i<size; …

9
Swift Betaのパフォーマンス:配列の並べ替え
Swift Betaでアルゴリズムを実装していたところ、パフォーマンスが非常に低いことに気付きました。さらに深く掘り下げた後、ボトルネックの1つが配列の並べ替えと同じくらい単純なものであることに気付きました。関連する部分はここにあります: let n = 1000000 var x = [Int](repeating: 0, count: n) for i in 0..<n { x[i] = random() } // start clock here let y = sort(x) // stop clock here C ++では、同様の操作に私のコンピューターで0.06秒かかります。 Pythonでは、0.6秒かかります(トリックのない、整数のリストの場合はy = Sorted(x)のみ)。 Swiftでは、次のコマンドでコンパイルすると6秒かかります。 xcrun swift -O3 -sdk `xcrun --show-sdk-path --sdk macosx` また、次のコマンドでコンパイルすると、88秒もかかります。 xcrun …

6
速度ではなくサイズを最適化すると、GCCが15-20%速いコードを生成するのはなぜですか?
私が2009年に最初に気付いたのは、GCC(少なくとも私のプロジェクトと私のマシン上で)が、 -Os速度(-O2または-O3)ではなくサイズ()です。 私はなんとかこの驚くべき動作を示し、ここに投稿するのに十分なほど小さいコードを作成することに成功しました。 const int LOOP_BOUND = 200000000; __attribute__((noinline)) static int add(const int& x, const int& y) { return x + y; } __attribute__((noinline)) static int work(int xval, int yval) { int sum(0); for (int i=0; i<LOOP_BOUND; ++i) { int x(xval+sum); int y(yval+sum); int z = add(x, y); sum += …

1
Rustコンパイラーは、2つの可変参照がエイリアスできないと想定してコードを最適化しないのはなぜですか?
私が知る限り、参照/ポインタのエイリアスは、最適化されたコードを生成するコンパイラの機能を妨げる可能性があります。これは、2つの参照/ポインタが実際にエイリアスである場合に、生成されたバイナリが正しく動作することを保証する必要があるためです。たとえば、次のCコードでは、 void adds(int *a, int *b) { *a += *b; *a += *b; } フラグをclang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)付けてコンパイルすると、-O3 0000000000000000 <adds>: 0: 8b 07 mov (%rdi),%eax 2: 03 06 add (%rsi),%eax 4: 89 07 mov %eax,(%rdi) # The first time 6: 03 06 add (%rsi),%eax 8: 89 07 mov %eax,(%rdi) # …

12
TensorflowをSSE4.2およびAVX命令でコンパイルする方法は?
これは、Tensorflowが機能しているかどうかを確認するスクリプトの実行から受け取ったメッセージです。 I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcublas.so.8.0 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcudnn.so.5 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcufft.so.8.0 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcuda.so.1 locally I tensorflow/stream_executor/dso_loader.cc:125] successfully opened CUDA library libcurand.so.8.0 locally W tensorflow/core/platform/cpu_feature_guard.cc:95] The TensorFlow library wasn't compiled to use …

2
Cでの&&&操作とは
#include <stdio.h> volatile int i; int main() { int c; for (i = 0; i < 3; i++) { c = i &&& i; printf("%d\n", c); } return 0; } 上記を使用してコンパイルされたプログラムの出力は次のとおりgccです。 0 1 1 と-Wallや-Waddressオプション、gcc警告を発行します。 warning: the address of ‘i’ will always evaluate as ‘true’ [-Waddress] c上記のプログラムでどのように評価されていますか?

3
GCCがほぼ同じCコードに対して、このように根本的に異なるアセンブリを生成するのはなぜですか?
最適化されたftol関数を書いているとき、私はいくつかの非常に奇妙な動作を見つけましたGCC 4.6.1。最初にコードを示します(明確にするために、違いを示しました)。 fast_trunc_one、C: int fast_trunc_one(int i) { int mantissa, exponent, sign, r; mantissa = (i & 0x07fffff) | 0x800000; exponent = 150 - ((i >> 23) & 0xff); sign = i & 0x80000000; if (exponent < 0) { r = mantissa << -exponent; /* diff */ } else { r …

4
整数の範囲を指定してオプティマイザにヒントを与えることはできますか?
intタイプを使用して値を格納しています。プログラムのセマンティクスにより、値は常に非常に小さな範囲(0〜36)で変化し、int(a charではなく)はCPUの効率のためにのみ使用されます。 このような小さな範囲の整数に対して、多くの特別な算術最適化を実行できるようです。これらの整数に対する多くの関数呼び出しは、「魔法の」操作の小さなセットに最適化される可能性があり、一部の関数は、テーブルルックアップに最適化されることもあります。 それで、これintが常にその小さな範囲にあることをコンパイラーに伝えることは可能ですか?そしてコンパイラーがそれらの最適化を行うことは可能ですか?

2
なぜラムダは単純な関数よりもコンパイラによって最適化できるのですか?
彼の本の中でThe C++ Standard Library (Second Edition)Nicolai Josuttisは、ラムダは単純な関数よりもコンパイラによってより最適化できると述べています。 さらに、C ++コンパイラは、通常の関数よりもラムダを最適化します。(213ページ) 何故ですか? インライン化に関しては、これ以上何の違いもないはずだと思いました。私が考えることができる唯一の理由は、コンパイラーがラムダを使用したより良いローカルコンテキストを持っている可能性があり、そのようなことがより多くの仮定を行い、より多くの最適化を実行できるためです。

5
どのフラグ-march = nativeがアクティブになるかを確認するにはどうすればよいですか?
GCC 4.3を使用してC ++アプリをコンパイルしています。私が使用している最適化フラグを手動で選択する代わりに-march=native、理論上は、コンパイルしているハードウェアに適用可能なすべての最適化フラグを追加する必要があります。しかし、どのフラグを実際に使用しているかを確認するにはどうすればよいですか?

2
ShapelessでのNatタイプの制限
無形の場合、Nat型は、型レベルで自然数をエンコードする方法を表します。これは、たとえば固定サイズのリストに使用されます。タイプレベルで計算を行うこともできます。たとえば、N要素のリストに要素のリストを追加し、Kコンパイル時にN+K要素があることがわかっているリストを取得します。 この表現は、たとえば10000002または53のような大きな数を表すことができますか、それともScalaコンパイラーが諦めることになりますか?

5
拡張GCC 6オプティマイザが実用的なC ++コードを壊すのはなぜですか?
GCC 6には新しいオプティマイザ機能があります。それthisは常にがnull ではないことを想定し、それに基づいて最適化します。 値の範囲の伝播は、C ++メンバー関数のthisポインターがnullでないことを前提としています。これにより、一般的なnullポインターチェックが不要になりますが、一部の非準拠コードベース(Qt-5、Chromium、KDevelopなど)も破損します。一時的な回避策として、-fno-delete-null-pointer-checksを使用できます。間違ったコードは、-fsanitize = undefinedを使用して識別できます。 変更文書は、頻繁に使用される驚くべき量のコードを破壊するため、これを危険だと明確に呼んでいます。 なぜこの新しい仮定が実用的なC ++コードを壊すのでしょうか?不注意または知識のないプログラマーがこの特定の未定義の動作に依存する特定のパターンはありますか?if (this == NULL)不自然なため、誰も書いていないようです。

7
コンパイラが予測可能な加算ループを乗算に最適化できない(またはできない)のはなぜですか?
これは、質問に対するMysticialの素晴らしい答えを読んでいるときに思い浮かんだ質問です。なぜ、ソートされていない配列よりもソートされた配列を処理する方が速いのですか? 関連するタイプのコンテキスト: const unsigned arraySize = 32768; int data[arraySize]; long long sum = 0; 彼の答えで彼はIntel Compiler(ICC)がこれを最適化すると説明しています: for (int i = 0; i < 100000; ++i) for (int c = 0; c < arraySize; ++c) if (data[c] >= 128) sum += data[c]; ...これと同等のものに: for (int c = 0; c < arraySize; …

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.