C#でのアライメント – プログラミング – Home

通知
すべてクリア

[解決済] C#でのアライメント


Air
 Air
(@Air)
ゲスト
結合: 20年前
投稿: 33
Topic starter  

お世話になります、Air です。
C# でのアライメントのとり方について質問です。

算術系のクラス等を自作した場合
計算に SIMD 等を使っているとどうしても
クラスを16バイトアライメント等で確保しなくてはならない
場合が出てきます。

C++ の時は 15バイトほど多めにとってみたいな風にしていたのですが
C# の場合はどのようにすればよろしいのでしょうか?

ご教示よろしくお願いします。

・開発環境
  WindowsXP
Visual Studio .NET2003


引用未解決
トピックタグ
C#
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

StructLayout属性のPackフィールドで設定できます。


返信引用
Air
 Air
(@Air)
ゲスト
結合: 20年前
投稿: 33
Topic starter  

レスありがとうございます。

これは Pack = 16 ということでしょうか?

ちなみに、float 型の変数を4つ持ったクラスを宣言する際
Pack = 16 としてしまうと、クラスの大きさは64バイト
みたいになってしまったりしますよね?


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

> ちなみに、float 型の変数を4つ持ったクラスを宣言する際
> Pack = 16 としてしまうと、クラスの大きさは64バイト
> みたいになってしまったりしますよね?

試してみましたか?

---- コード ----
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack=16)]
struct Test
{
public float f1;
public float f2;
public float f3;
public float f4;
}

class Class1
{
static void Main ()
{
Console.WriteLine(Marshal.SizeOf(typeof(Test)));
}
}

---- 結果 @ Visual C#.NET 2003 ----
16

まぁ,所詮はアンマネージコードの世界だけでの話ですが……。


返信引用
Air
 Air
(@Air)
ゲスト
結合: 20年前
投稿: 33
Topic starter  

し、失礼いたしました。
ネットで得た知識のみで発言していました、すいません。
たしかにおっしゃられる通りの結果でした。

ちなみに、他にも試してみたのですが

[StructLayout(LayoutKind.Sequential, Pack=16)]
struct Test00
{
public float f1;
public float f2;
public short s1;
public short s2;
}

[StructLayout(LayoutKind.Sequential, Pack=16)]
struct Test01
{
public short s1;
public short s2;
public float f1;
public float f2;
}

[StructLayout(LayoutKind.Sequential, Pack=16)]
struct Test02
{
public float f1;
public float f2;
public float f3;
public short s1;
}

[StructLayout(LayoutKind.Sequential, Pack=16)]
struct Test03
{
public short s1;
public float f1;
public float f2;
public float f3;
}

Test00 と Test01 のサイズは12と出ました。
これは大いに納得です。
ですが、Test02 と Test03 は共にサイズは16と出ました。
float 3つに short 1つだから14じゃないの?と思うのですが・・・
ちなみに

[StructLayout(LayoutKind.Sequential, Pack=16)]
struct Test04
{
public float f1;
public short s1;
public float f2;
public short s2;
}

このパターンもサイズは16と出ました。
何か私が根本的に勘違いでもしてるのでしょうか?

おわかりになる方、説明していただけませんでしょうか?
よろしくお願いします。


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

あんまりC#でアラインなんて考える必要ないのですが……。
# そもそも,マネージコード中での構造体の配置は完全には決まっていないはず。

> ですが、Test02 と Test03 は共にサイズは16と出ました。
> float 3つに short 1つだから14じゃないの?と思うのですが・・・

Test02やTest03のマーシャリングした結果のサイズが14バイトだと,
アンマネージな配列を作った時に,
・1個目の要素は4の倍数のアドレスに置かれる
・2個目の要素は4の倍数+2のアドレスに置かれる
というような状況が発生してしまいます。

これだとfloat要素が4の倍数のアドレスに置かれなくなるため,
良くない状況が発生してしまいます。

基本的に,各要素のアラインは,
要素のサイズと指定されたアラインの小さい方の値になります。
そして,オブジェクトのサイズは最大のアラインの値の倍数になります。

> このパターンもサイズは16と出ました。

+00 : f1 <align:4>
+04 : s1 <align:2>
+08 : f2 <align:4>
+0C : s2 <align:2>

と配置され,全体のアラインは4ですから,
14以上で最小の4の倍数である16が,
Test04のアンマネージへマーシャリングされた時のサイズになります。

# あぁ,どこがC#の話なんだか……。


返信引用
匿名
 匿名
(@匿名)
ゲスト
結合: 1秒前
投稿: 0
 

なるほど!おおいに納得しました。

ていうか、アライメントとかをそこまで気にするようなプログラムなら
おとなしくC++で書けよってとこですかね。

丁寧なご説明ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました