2012-01-23 5 views
10

今日、私は、約40個の要素からなる構造全体がゼロであるかどうかを判断する必要があるという状況に遭遇しました。
可能な限り迅速かつ効率的にするためにどのように考えて、私はそうする3種類の方法を考えた:構造体をゼロと比較するのに好ましい方法

  1. は、if文40をその結果、ゼロに各要素を比較します。
  2. 既に構造化された同様の構造体を割り当て、memcmp構造体を割り当てます。
  3. 構造体をすべてをカバーできる大きさのユニオンでラップします。
例えば

typedef union { 
    struct { 
    uint8_t a; 
    uint8_t b; 
    } 
    uint16_t c; 
} STRUCTURE_A; 

とゼロとの比較。

私はこれらのソリューションについてどのようなことが考えられているか知りたいと思います。その中で最も速く効率的なソリューションを見つけてください。
あなたがもっと良いアプローチのものを教えてください...
ありがとう。

+0

ゼロフラグのように、 'if'文で構造体全体をチェックするだけで何が問題になりますか? –

+3

パディングについて忘れないでください! – NPE

+1

3つの異なる方法のそれぞれを実装し、そのパフォーマンスを比較しましたか?あなたは何を見つけましたか? –

答えて

15

は、(構造オブジェクトの一つは、すべてのメンバーが値0に設定されている場合でも)これは、2つの構造体のオブジェクトを比較するための唯一の安全な方法である0

に構造体のすべてのメンバーを比較してください。構造体を比較するのにmemcmpを使用しないでください。構造体のパディングのバイトの値は指定されていません。また、構造体オペランドのオペランド==を使用することはできません。

構造オブジェクトの比較で、このC-FAQのリンクを参照してください:

Q: Is there a way to compare structures automatically?

+1

構造体にパディングが含まれていないことを確認していれば、 'memcmp'は安全です。実装は技術的に任意の無意味なパディングを追加することが許されていますが、実際のパディングは完全にアラインメントのためのものであり、正しく構築され、自然にアライメントされた構造は潜在的に最後を除いてパディングを持ちません。特に、 'intX_t'を使ってアラインメントギャップを持たないように並べ替えることは、パディングを避けるための良い方法です。 –

+0

構造体にパディングが含まれておらず、 'memcmp'が実際には*高速であれば、オプティマイザは必ずそれを見て、それに応じて比較を変換します。 –

+0

うまくいけば...... –

1

あなたの構造のサイズは< =プロセッサのワードサイズである場合、あなたはあなたの労働組合のトリックは、しかし、何か良いコンパイラを行うことができますこれを自動的に行う必要があります。つまり、ifをコンパクトにまとめることができます。これにより、明確にすることができますが、パフォーマンスは維持されます。

0

コードを明確にするために、また、パディングによって生じる問題を避けるために、各メンバーをチェックするのが最善の方法であることも指摘しています。

スピードを上げるために、各バイトがゼロであるかどうかを確認するだけのような方法で始めます。

int iszero(void * ptr, int bytes) 
{ 
    char * bptr = (char*)ptr; 
    while(bytes--) 
    if(*bptr++) 
     return 0; 
    return 1; 
} 

次に、ワード単位で比較するように最適化します。どのように行われたかについての例は、newlibの実装を確認してください。strlen() & memcpy()

+0

これは 'memcmp'に相当し、パディングの問題があるかもしれません。 –

+0

@R ..いいえ、memcmp()と同じではありません。なぜならここには余分な構造体が存在しないからです。 memcmp()の余分なメモリアクセスは、たびに2回の読み込みを行い、大規模な構造体にキャッシュが壊れている可能性があるため、メモリアクセス時間の2倍よりも悪い可能性があります。私はパディングの問題を考慮していなかった。しかし、パディング(たとえば、プラグマパックを使用しているGCCなど)がないことがわかっている場合は、この手法が最速であるという私の議論に立つでしょう。 –

+0

「同等」とは、同じ動作(およびパディングの問題)があることを意味しましたが、パフォーマンスを比較することをお勧めします。あなたのコード(バイト単位)は非常に遅いため、複数の読み込みでも 'memcmp'が勝つはずです。良い 'memcmp'は、一度に4バイト、8バイト、または16バイトを比較します。 BTWの "packed"はアラインメントの問題を解決する方法ではありません。 ouahの答えに対する私のコメントは正しい方法です。 –

関連する問題