質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

Q&A

3回答

5051閲覧

アラインメントのサイズ

strike1217

総合スコア651

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GCC

GCCはGNU Compiler Collectionの略です。LinuxのC言語コンパイラのデファクトスタンダードであり、数多くの他言語やプラットフォームサポートもします。

1グッド

1クリップ

投稿2017/09/25 05:12

構造体のアラインメントについては過去に質問したので、今回は別の話です。

リンク内容

4バイト整数または4バイト浮動小数をメモリに格納する場合, 先頭アドレスが4の倍数になるようにすれば上図の1ワードに収まるため, 1回のメモリアクセスで読み書きできる. このようにデータの先頭アドレスを4の倍数にすることを, 「4バイト境界にアライン (align:整列,位置合わせ) する」という.

64bitシステムだと8Bなので、8の倍数にすれば美しくなるんですかね。

char buf[a]; // aが8の倍数

ところがアセンブリ言語を見ると64bitでもスタックは32bitです。
つまり64bitでもアラインメントは4の倍数にしなくてはダメという事ですよね?
このサイトの説明が変なのでしょうか?
8B? 4B?

私の本の中にこう書いてあります。

malloc() calloc() realloc()により割り当てたメモリについては、C言語すべての標準の型を正しくアラインメントするようにPOSIXでも定義されています。Linuxでも上記ライブラリ関数は、32bitシステムは8バイト境界に、64bitシステムでは16バイトにアラインメントします。

ヒープ領域はスタックとは別物なのでアラインメントも異なるという事ですかね。
各領域ごとにアライメントが決められているんでしょうか??

1回のメモリアクセスで読み書きできる. このようにデータの先頭アドレスを4の倍数にすること

この説明では全く分かりません。
CPUによって固定ならどんな領域でも64bitなら8Bにしなくてはならないはずです。

さらに謎な点が・・・
アライメントはそのシステムのアーキテクチャによって固定ですよね?

#define _XOPEN_SOURCE 600 #define GNU_SOURCE #include<stdlib.h> int posix_memalign(void **memptr, size_t alignment, size_t size);

任意のサイズでアラインメントを可能にする関数ですが、任意のアライメントってどういうことですか??

Linux 64bit x86_64です。

kazuyakazuya👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

質問文から察するに、「アラインメント要件」と「(実際の)アラインメント」を混同されているようです。

  • アラインメント要件:CPUアーキテクチャにおいて、型(type)毎に 最低限満たすべき アラインメントが決められています。例:char型では1int型では4double型では8など。
  • (実際の)アラインメント:プログラム実行時に決まる、変数や動的確保メモリのアドレス値。例:malloc()関数が確保するメモリ領域のアライメントは8など。

(実際の)アライメントは、アライメント要件を満たす必要があります。mallocが返したアドレス値のアラインメントが8であれば、それより 小さいアライメント要件を持つ 型(type)を安全に格納できます。maisumakunさん回答にある「大は小を兼ねる」のイメージが分かりやすいかと思います。


各領域ごとにアライメントが決められているんでしょうか??

(実際の)アライメントは、コンパイル(静的リンク)およびプログラムロード(動的リンク)に決定されます。つまり、プログラムがメモリ上にロードされるときまでに最終決定されるものです。

アライメントはそのシステムのアーキテクチャによって固定ですよね?

「アライメント要件」はアーキテクチャで決まります。

任意のアライメントってどういうことですか?

前述の説明通りです。C言語の仕様により、「動的確保されるメモリアドレスには、任意の型を配置できること」が保証されています。

投稿2017/09/26 09:44

yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2017/09/26 11:54

スタック領域が4Bであることは、アライメント要件の方ですか?
yohhoy

2017/09/26 13:24 編集

狭義のアライメント要件は 型(type) に対する要件のみを指すことが多いです。それ以外には、ABI(Application Binary Interface) により追加でアライメント要件を要請されることがあります。スタックについては https://qiita.com/yohhoy/items/54633faf0546f8cd0e3a をどうぞ。
strike1217

2017/09/26 13:36

むむ・・・難しい・・・ 「アラインメント要件」と「(実際の)アラインメント」は別物ですよね。 実際のメモリのレイアウトはアラインメント要件とは必ずしもピッタリと一致していないという事でしょうか? 実際のアラインメントは動的確保の場合は実行時に決まりますが、スタックの場合はアセンブル段階で決まるんですか?リンカ段階ですか?
yohhoy

2017/09/26 13:46 編集

> 実際のメモリのレイアウトはアラインメント要件とは必ずしもピッタリと一致していないという事でしょうか? はい。maisumakunさんコメントや本回答をもう一度ご確認ください。例えば、int型のアライメント要件が4の場合、実際のアライメントは4または8または16または32...であればOKです。 > スタックの場合はアセンブル段階で決まるんですか?リンカ段階ですか? いずれでもなく、実行時です。例えば https://teratail.com/questions/25921 の質問文中では、「and esp,0xfffffff0」のように実行時にスタックポインタ・レジスタ(esp)の値を調整しています。
strike1217

2017/09/26 13:56

>「and esp,0xfffffff0」のように実行時にスタックポインタ・レジスタ(esp)の値を調整しています。 objdumpなどしたアセンブリを見れば実際のアライメントが分かるんですね! 「CPUが64bitなら8バイト境界」とはどういう事でしょうか? これは実際のアライメントの方の話ですかね?
yohhoy

2017/09/26 14:01

> 「CPUが64bitなら8バイト境界」とはどういう事でしょうか? ??? どこから出てきた話ですか?
YsMana

2017/09/26 14:41

> http://www5d.biglobe.ne.jp/~noocyte/Programming/Alignment.html > 「アラインメントは何か?」のところです。 そこには「現実には,Nビット CPU のデータバス幅がNビットであるとは限らない.x86 を例に取ると,32ビット CPU とは言いながら Pentium 以降は64ビット・データバスである.」と書かれていますし、 さらに「誤解1:(32ビット CPU では) 構造体は常に4バイト境界に配置される.」というセクションまで作って説明がされていますよ。 たぶんあなたは誤解1をやった人(の1人)です。
strike1217

2017/09/26 14:45

むむ・・・ 「現実には,Nビット CPU のデータバス幅がNビットであるとは限らない.」 そうですね。 では、CPUのbit数はアライメントとは何の関係もない・・・ということで良いんですかね?
YsMana

2017/09/26 15:27

> https://teratail.com/questions/37555 > 「32bit CPUなら4バイト境界、64bit CPUなら8バイト境界が多いです。 」 こっちの方の発言も、文脈から「double型のアラインメント」の話であって、アラインメント全般の話じゃないですね。(その前にshort型のアラインメントが2という話も出てきますし。) それに、「境界をどこに調整するかは処理系(主にCPUの都合)によって異なり、32bit CPUなら4バイト境界、64bit CPUなら8バイト境界が『多い』です。」 と言っているのであって、CPUが64bitなら『必ず』8バイト境界なんて言ってないですよ。
strike1217

2017/09/26 15:42

ふむー。だんだんわかってきました。
a_saitoh

2017/09/28 04:15

アライメントがずれてても遅い(一つのデータを取得するのにデータバスを2回使う)だけで動くには動く、ってCPUもありますね。
guest

0

アライメントはそのシステムのアーキテクチャによって固定ですよね?

いえ、状況によってアラインメントは異なります

マシン内では、整数のアライメントはふつう、整数自体の長さ以下となります(そうでないと、整数配列に隙間が空いて、効率が悪くなります)。32ビット整数なら4バイト境界、64ビット整数なら8ビット境界、SSEで使うような128ビット整数は16バイト境界というようになることもあります。もちろん、1バイトのchar好きな場所に置けます

malloc()のアライメントは、大きな型の変数を入れても問題ないように、大きなアライメントを取るようになっています…が、SSEなどアセンブラで特殊な型を触る場合にはそれでも合わないので、手動調整が必要になる場合もあります。

「アライメントを手動で調整する機能」は、基本的に「バイナリデータが特定のアライメントで決め打ちになっているような場合」に使うもので、処理中にずらすようなことはあまり行いません。

投稿2017/09/25 05:23

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2017/09/25 05:29 編集

前から思っていたんですが、変数の型のサイズとアラインメントって何が違うんですか? 偶然同じなんですか? int : 4B char 1B
maisumakun

2017/09/25 05:39 編集

x86の浮動小数点計算は、(x64でSSEに移行するまで)80ビット精度があったので、それをそのまま扱う「long double」を使える環境もありました。 ただ、「10バイトアライン」では処理の手間なので、4バイトや8バイトで切り上げてアラインすることになります(sizeofもアライメントに合わせる隙間を入れて、12バイトや16バイトとなります)。
strike1217

2017/09/25 05:47

アライメントは変数によっても異なり、領域によっても異なるという事ですかね??
maisumakun

2017/09/25 05:53 編集

mallocの場合の扱いは、「領域の違い」というより「何が入るかわからないから、大きめに取っている」という話です(16バイト境界に揃えておけば、8バイト・4バイトなどのアラインとして使っても全く問題ないので、「大は小を兼ねる」ということです)。
strike1217

2017/09/25 05:59

あ、なるほど!ヒープの場合はそういう考え方なんですね!
guest

0

「アライメントとは?」については皆さんの回答と議論がすでにあるので、
posix_memalign()についてだけ。

posix_memalign() は通常用途ではなく、ハードに依存してて例えば1024バイトきざみのアドレスでないとうまく動作しない、あるいはその方が速くなる、というような条件がある場合に利用します。

通常のアプリケーションでも本来は意識しなければならないデータバスの問題とかであれば、コンパイラとライブラリがアーキテクチャ(x64など)を理解しているのでmalloc()で良いです。

投稿2017/09/28 05:26

daisuke7

総合スコア1563

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2017/09/29 15:03

う~~~ん。 大きなアライメントが必要になる場面がいまいちよくわからないんですよね。
daisuke7

2017/10/02 05:53

ぱっと思いつくのは、sysconf()やmlock()あたりと組み合わせて、ページ境界に合わせてメモリ確保&ページロックしちゃうようなコードを書きたいときとか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問