読者です 読者をやめる 読者になる 読者になる

gcc4.8 でメモリアライメント管理が使用可能になった

C/C++ SIMD OpenCL

メモリアライメントについて

gcc4.8 においてメモリアライメント管理である alignas と alignof の使用が可能となりました.alignas と alignof は C++ 0x から言語的にサポートされており*1,alignas と alignof を使用してプログラムを記述することでコンパイラに依存しないプログラムの作成が可能となります.

 GCC と Clang のサポート状況が以下のサイトにまとめられています.(2013/04/30 では Clang のほうはまだアライメント関係を正式サポートしていないようです)

alignas と alignof について

alignas:変数宣言時にメモリアライメントを指定する
//ex1. byte で指定する
alignas(16) double pi = 2.0 * acos(0.0);

//ex2. 型で指定する
alignas(float) float x = 3.12;

//ex3. ある変数と同じにする
alignas(alignof(x)) y = 2.71;

//ex4. 配列
alignas(32) double sum[4];
alignof:変数に設定されているアライメントを取得する
std::size_t n = alignof(pi);
std::size_t x_n = alignof(x);

サンプルコード

/**--------------------
   main.cpp
   --------------------*/

#include <iostream>
#include <cmath>

int main(void){
  //ex1. byte で指定する
  alignas(16) double pi = 2.0 * acos(0.0);
  std::size_t n = alignof(pi);
  std::cout << "pi = " << pi 
	    << ", n = " << n << std::endl;

  //ex2. 型で指定する
  alignas(float) float x = 3.12;
  std::cout << "x = " << x 
	    << ", alignof(x) = " << alignof(x) << std::endl;
  
  //ex3. ある変数と同じにする
  alignas(alignof(x)) float y = 2.71;
  std::cout << "y = " << y 
	    << ", alignof(y) = " << alignof(y) << std::endl;
  
  //ex4. 配列
  alignas(32) double sum[4];
  std::cout << "alignof(sum) = " << alignof(sum) << std::endl;
  
  return 0;
}

コンパイル方法と実行結果

コンパイル方法
$ g++-mp-4.8 main.cpp -std=c++11
実行結果
pi = 3.14159, n = 16
x = 3.12, alignof(x) = 4
y = 2.71, alignof(y) = 4
alignof(sum) = 32

余談

従来,gcc はメモリアライメントを設定するために __attribute__(aligned(x)) を gcc 独自の拡張機能として提供していました.gcc4.8 でアライメント管理がサポートされましたが,Clang がまだ対応していないことや,OpenCL で __attribute__() 属性修飾子が取り入れられるなど,すぐに切り替わるということはなさそうです.