#c #openmp #intel #icc
#c #openmp #intel #icc
Вопрос:
У меня есть простой код, который использует pragma в определениях макросов. Код компилируется и отлично работает с использованием QtMinGW просто отлично.
#include <omp.h>
#include <stdio.h>
#define NUMEL 1024
#define OMP_PARALLEL _Pragma("omp parallel")
#define OMP_FOR _Pragma("omp for")
#define main_func(par)
int main(){
int a[NUMEL];
OMP_PARALLEL
{
int i;
OMP_FOR
for (i=0; i<NUMEL; i ){
printf("THRD : %d n", omp_get_thread_num());
a[i] = tan(i*2);
}
}
return 0;
}
main_func(par)
Однако, если я использую компилятор Intel C (ICC) (icl.exe в Windows) он выводит следующую ошибку:
error: expected a ";"
main_func(par)
Методом проб и ошибок я заметил, что если добавить; в строке of, как показано ниже, ошибка изменяется на ошибку linke:
#define OMP_PARALLEL _Pragma("omp parallel");
#define OMP_FOR _Pragma("omp for");
ОШИБКА ССЫЛКИ
test_omp.obj : error LNK2019: unresolved external symbol _Pragma referenced in function main
test_omp.exe : fatal error LNK1120: 1 unresolved externals
make: *** [Makefile:16: test_omp] Error 1120
Любой комментарий очень ценен.
Ответ №1:
После нескольких попыток и ошибок некоторые вопросы и ответы на форуме icc выясняются
- _Pragma следует заменить на __pragma
- нет необходимости в кавычках
таким образом, синтаксис intel / icc для использования прагм omp в определении макросов должен быть исправлен, как показано ниже:
#define OMP_PARALLEL __pragma(omp parallel)
#define OMP_FOR __pragma(omp for)
Я надеюсь, что это поможет другим… Я оставляю тестовый код и makefile, чтобы вы тоже попробовали себя. Мне потребовалось 3 дня, чтобы разобраться с этим.
Не стесняйтесь голосовать за мои вопросы и ответы, если сочтете это полезным.
#include <omp.h>
#include <stdio.h>
#define NUMEL 1024
#define OMP_PARALLEL __pragma(omp parallel)
#define OMP_FOR __pragma(omp for)
#define main_func(par)
int main(){
int a[NUMEL];
OMP_PARALLEL
{
int i;
OMP_FOR
for (i=0; i<NUMEL; i ){
printf("THRD : %d n", omp_get_thread_num());
a[i] = tan(i*2);
}
}
return 0;
}
main_func(par)
int main2(){
int a[NUMEL];
#pragma omp parallel
{
int i;
#pragma omp for
for (i=0; i<NUMEL; i ){
printf("THRD : %d n", omp_get_thread_num());
a[i] = tan(i*2);
}
}
return 0;
}
PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
CXX=icl
CC=icl
LD =xilink
LIBDIR=Debug/lib/
OBJDIR=Debug/obj/
CFLAGS=/Qopenmp
LDFLAGS= /nodefaultlib:vcomp libiomp5md.lib
OBJS = $(OBJDIR)test_omp.obj
all: test_omp
test_omp: $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) -Fe:test_omp.exe
$(OBJDIR)%.obj: $(PROJECT_ROOT)%.cpp
$(CXX) -c $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -Fo:$@ $<
$(OBJDIR)%.obj: $(PROJECT_ROOT)%.c
$(CC) $(CFLAGS) $(CPPFLAGS) -Fo:$@ -c $<
clean:
rm -fr test_icl $(OBJS) test_omp.exe
Комментарии:
1. Возможно, вам захочется
-march=native
, если вы собираетесь работать на том же компьютере, на котором вы строите, включить расширения ISA, которые у него есть. Вместо просто базового SSE2. Я думаю, что ICL включает оптимизацию по умолчанию (в отличие от других компиляторов), поэтому, вероятно, можно не-O3
учитывать.