bugfix> c++ > 投稿

私は int128_t が存在することを知っていますCおよびC ++を入力します。

2つのスレッドがあり、1つがこの128ビット整数を含むメモリ位置から読み取り、もう1つが書き込みを行っている場合。

この値が2つの64ビット整数の書き込みとして書き込まれる可能性がありますか、それとも1つの128ビット整数の書き込みになりますか?

回答 3 件
  • サポートについては、他の回答で説明しています。実装の問題について説明します。

    通常、メモリから読み取るとき、コンパイラはメモリからレジスタにデータをフェッチするプロセッサ命令を発行します。これは、プロセッサとメモリ間でデータバスがどのように設定されているかに応じてアトミックになる場合があります。

    プロセッサが128ビット転送をサポートし、メモリが128ビットデータバスをサポートしている場合、これは単一のフェッチ(または書き込み)である可能性があります。

    プロセッサが128ビットの{register}転送をサポートしているが、データバスが小さい場合、プロセッサはメモリからデータを転送するのに十分なフェッチを実行します。これは、アトミックの定義に応じて、アトミックである場合とそうでない場合があります(1つのプロセッサ命令ですが、複数のフェッチが必要な場合があります)。

    128ビットのレジスタ転送をサポートしないプロセッサの場合、コンパイラはメモリをレジスタに読み込むのに十分な命令を発行します。これは、レジスタからメモリへ、またはメモリからレジスタへの転送用です。

    メモリからメモリへの転送(変数の割り当てなど)の場合、コンパイラはブロックの読み取りと書き込みを使用することを選択できます(プロセッサがブロックの読み取りと書き込みをサポートしている場合)。 SIMDをサポートしているプロセッサーもあれば、ブロック転送命令を持っているプロセッサーもあります。たとえば、ARMには、多数のレジスタをメモリからロードし、多数のレジスタをメモリに格納するためのLDM(複数ロード)およびSTM(複数格納)命令があります。ブロックの読み取りと書き込みの別の方法は、DMAデバイス(存在する場合)を使用することです。プロセッサが他の命令を実行している間、DMAはデータを転送できます。ただし、DMAを使用するオーバーヘッドには、16個の8バイト(バイト)転送を使用するよりも多くの命令が必要になる場合があります。

    要約すると、コンパイラは int128_t をサポートする必要はありません。 。サポートしている場合は、プロセッサとプラットフォームのハードウェアサポートに応じて、データを転送するさまざまな方法があります。アセンブリ言語を表示して、 int128_t をサポートするためにコンパイラーによって発行される命令を確認します 。

  • CもC ++も int128_t を持つ必要はありません  コンパイラがそのタイプをサポートしている場合、タイプしなければならない  signed になる  2の補数の128ビット整数型。しかし、原子性は要件ではありません。

    読み書きの動作どれか 同時にアトミックではないタイプは未定義

    C ++で、 std::atomic<int128_t> を使用できる場合  そして、あなたのプラットフォームならする アトミック int128_t を持っている  その後、それは typedef より少し多くなります 。

    それ以外の場合、およびCでは、コンパイラーかもしれない アトミック128ビット整数型を持っています。そうでない場合は、インラインアセンブリを使用して独自のバージョンをロールできます。

  • まず、あります番号  int128_t  C ++で入力します。最大の標準タイプは int64_t です 。

    2番目に、一部のプラットフォームは拡張機能として128ビット整数型を提供します。たとえば、gcc/clang/iccサポート __int128  タイプ。

    マルチスレッドシナリオでこのタイプを正しく使用するには、他のタイプと同様に、適切な同期構造でアクセスを保護するか、 std::atomic<__int128> を使用します。 。 __int128 をサポートするプラットフォーム 、通常はアトミックバージョンもサポートしています。

    そして、単にあなたの好奇心を満たすために、128ビット整数をネイティブにサポートできる現在使用されている一般的なハードウェアは知りません。

あなたの答え