내 제안은 각 명령어 세트 (예 : Xnosse.o Xsse3.o Xsse4.o 등)에 대해 별도의 단위를 컴파일하고이를 위해 자동 디스패처를 사용합니다. 사용자는 자신의 PC에서 최상의 성능을 얻고 내부 세부 사항을 신경 쓰지 않아도됩니다.
코드를 라이브러리에 작성 했으므로 라이브러리로드시 호출 될 init 함수를 사용하여 자동으로로드 시간에 대한 디스패치를 결정할 수 있습니다. 이 결정은 함수가 실제로 호출 된 첫 번째 시간에만 실행되도록 만들 수 있습니다. 이것은 지연 바인딩을위한 것입니다.
다음은 코드 예입니다 (gcc에만 해당!)
컴파일 단위 : 라이브러리에 이제
//Xnosse.c
void do_some_math_stuff_no_sse(int x, int y)
{
...do some sophisticated math stuff with no sse support
}
void do_some_other_math_stuff_no_sse(int x, int y)
{
...do some other sophisticated math stuff with no sse support
}
//Xsse3.c
void do_some_math_stuff_sse3(int x, int y)
{
...do some sophisticated math stuff with sse3 support
}
void do_some_other_math_stuff_sse3(int x, int y)
{
...do some other sophisticated math stuff with sse3 support
}
//Xsse4.c
void do_some_math_stuff_sse4(int x, int y)
{
...do some sophisticated math stuff with sse4 support
}
void do_some_other_math_stuff_sse4(int x, int y)
{
...do some other sophisticated math stuff with sse4 support
}
:
//my_math.h
/* Following definitions are in my_math.c */
extern void (*do_some_math_stuff)(int x, int, y);
extern void (*do_some_other_math_stuff)(int x, int y);
//my_math.c
void not_set(int x, int y)
{
// If you don't want to use the constructor for any reason,
// say you want lazy binding, this will do the trick as our
// functions do_math_stuff and do_other_math_stuff are initialized
// to this one
setup();
}
void (*do_some_math_stuff)(int x, int, y) = not_set;
void (*do_some_other_math_stuff)(int x, int y) = not_set;
int detect_sse()
{
..Do runtime detection of sse version
}
/* The following function will be called when your library loads */
void __attribute__ ((constructor)) setup(void)
{
if (detect_sse() == 0)
{
do_some_math_stuff = do_some_math_stuff_no_sse;
do_some_other_math_stuff = do_some_other_math_stuff_no_sse;
}
else if (detect_sse() == 3)
{
do_some_math_stuff = do_some_math_stuff_sse3;
do_some_other_math_stuff = do_some_other_math_stuff_sse3;
}
else if (detect_sse() == 4)
{
do_some_math_stuff = do_some_math_stuff_sse4;
do_some_other_math_stuff = do_some_other_math_stuff_sse4;
}
}
당신이 게으른 바인딩하려면 설정에서 생성자 decorater를 제거하고 컴파일 :
gcc -Wall -shared -fPIC -o libmy_math.so my_math.c Xnosse.c Xsse3.c Xsse4.c
하는 경우 라이브러리에서로드 할 때 다음과 같은 추가 매개 변수를 사용하면 동적 디스패처가 실행되기를 원합니다. g cc :
gcc -Wall -shared -Wl,-init,setup -fPIC -o libmy_math.so my_math.c Xnosse.c Xsse3.c Xsse4.c
3은 여기에 ifs 또는 buts가 없습니다. –
@ n.m. 전에는 함수 포인터로 작업하지 않았으므로이 세 가지 모두가 꽤 우아하지 않게 보였다. 그러므로 질문입니다. –