私は最近、OpenMP をいじり始めて、とても気に入っています。
私は趣味のクラシック VB プログラマーで、VB プログラムの関数を C でコーディングするのが好きです。そのため、Windows 7 x64 と GCC 4.7.2 を使用しています。私は通常、すべての C 関数を 1 つの大きな C ファイルにセットアップし、それから DLL をコンパイルします。ここで、DLL で OpenMP を使用したいと考えています。
まず、簡単な例を設定し、そこから exe ファイルをコンパイルしました。
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n = 520000;
int i;
int a[n];
int NumThreads;
omp_set_num_threads(4);
#pragma omp parallel for
for (i = 0; i < n; i++)
{
a[i] = 2 * i;
NumThreads = omp_get_num_threads();
}
printf("Value = %d.\n", a[77]);
printf("Number of threads = %d.", NumThreads);
return(0);
}
私はそれを使用してコンパイルしgcc -fopenmp !MyC.c -o !MyC.exe
、それは魅力のように機能します。
ただし、DLL で OpenMP を使用しようとすると失敗します。たとえば、次の関数を設定します。
__declspec(dllexport) int __stdcall TestAdd3i(struct SAFEARRAY **InArr1, struct SAFEARRAY **InArr2, struct SAFEARRAY **OutArr) //OpenMP Test
{
int LengthArr;
int i;
int *InArrElements1;
int *InArrElements2;
int *OutArrElements;
LengthArr = (*InArr1)->rgsabound[0].cElements;
InArrElements1 = (int*) (**InArr1).pvData;
InArrElements2 = (int*) (**InArr2).pvData;
OutArrElements = (int*) (**OutArr).pvData;
omp_set_num_threads(4);
#pragma omp parallel for private(i)
for (i = 0; i < LengthArr; i++)
{
OutArrElements[i] = InArrElements1[i] + InArrElements2[i];
}
return(omp_get_num_threads());
}
もちろん、構造体は定義されています。私はそれを使用してコンパイルします
gcc -fopenmp -c -DBUILD_DLL dll.c -o dll.o
gcc -fopenmp -shared -o mydll.dll dll.o -lgomp -Wl,--add-stdcall-alias
コンパイラとリンカーは文句を言わず (警告も表示されません)、dll ファイルは実際にビルドされています。しかし、VB 内から関数を呼び出そうとすると、VB コンパイラは DLL ファイルが見つからないと主張します (実行時エラー 53)。奇妙なことに、.c ファイル内に 1 つの OpenMP "コマンド" が存在するとすぐに、OpenMP コードを 1 行も含まない関数を呼び出しても、VB コンパイラは DLL が見つからないと主張します。すべての OpenMP 要素をコメントアウトすると、関数は期待どおりに機能しますが、もちろん、並列化に OpenMP を使用しません。
ここで何が問題なのですか?事前に感謝します。:-)