기본 콘텐츠로 건너뛰기

Git 원격 브랜치 삭제

공유객체 속도

UNIX 공유객체(shared object) 만들기

테스트 환경을 만들기 전에 파일명을 소개하겠다.
  • Makefile - 빌드를 위한 스크립트
  • plgn.cpp - plgn.so를 위한 소스. func2 함수가 포함되어 있다.
  • sotest.cpp - 시간 측정을 위한 소스. func1 함수가 포함되어 있다.
일단 Makefile
TARGET=sotest plgn.so
CXXFLAGS=-g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT
LDFLAGS=-ldl

all:$(TARGET)

clean:
    $(RM) $(TARGET) *.o

sotest:sotest.cpp

plgn.so:plgn.o
    $(CXX) $(CXXFLAGS) -shared -lc -o $@ $<

plgn.o:plgn.cpp
    $(CXX) $(CXXFLAGS) -c -fPIC $<
뭐, 대충 흉내만 내놓고... 다음은 plgn.cpp
extern "C" void func2(volatile int*);

void
func2(volatile int* v)
{
    ++(*v);
}
역시나 흉내내기. extern "C"를 붙여 맹글링 회피 능력을 +3 했다. (뻘소리)
다음은 sotest.cpp
#include <iostream>
#include <dlfcn.h>
#include <sys/time.h>
using namespace std;

static const size_t testcount(1000000UL);

long long
getTimestamp(void)
{
    static struct timeval tv;
    gettimeofday(&tv, NULL);
    return 1000000LL*tv.tv_sec+tv.tv_usec;
}

extern "C" void func1(volatile int*);

typedef void (*func_t) (volatile int*);

void
func1
(volatile int* i)
{
    ++(*i);
}

void
testFunc(func_t f, const char* msg)
{
    static const long long t1(getTimestamp());
    volatile int v(0);
    for ( size_t i(0); i<testcount; i++ )
    {
        f(&v);
    }
    cout << msg << ": " << (getTimestamp()-t1)/1000.0 << " msec" << endl;
}

void
testSFunc(int flag, const char* msg)
{
    static void* handle(NULL);
    handle = dlopen("./plgn.so", flag);
    if ( !handle )
    {
        cout << dlerror() << endl;
        return;
    }

    int tip;
    func_t f((func_t)dlsym(handle,"func2"));
    f(&tip);
    testFunc(f, msg);
    dlclose(handle);
    handle = NULL;
}

int
main(int,char**)
{
    testFunc(func1,"Local");
    testSFunc(RTLD_LAZY|RTLD_LOCAL, "Shared(LAZY|LOCAL)");
    testSFunc(RTLD_NOW|RTLD_LOCAL, "Shared(NOW|LOCAL)");
    testSFunc(RTLD_LAZY|RTLD_GLOBAL, "Shared(LAZY|GLOBAL)");
    testSFunc(RTLD_NOW|RTLD_GLOBAL, "Shared(NOW|GLOBAL)");

    return 0;
}
자, 빌드해보자.
$make
g++ -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT -ldl sotest.cpp -o sotest
g++ -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT -c -fPIC plgn.cpp
g++ -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT -shared -lc -o plgn.so plgn.o
실행 결과는?
$ ./sotest
Local: 3.496 msec
Shared(LAZY|LOCAL): 7.221 msec
Shared(NOW|LOCAL): 10.786 msec
Shared(LAZY|GLOBAL): 14.349 msec
Shared(NOW|GLOBAL): 17.908 msec
느리구나... -_- 두 배나...

댓글

이 블로그의 인기 게시물

Bash Array, Map 정리

Bash에서 Array, Map에 대한 정리. (매번 찾기 귀찮) 찾아보진 않았지만, Bash에서 Array든 Map이든 동일하게 Map(C++에서 Unordered Map)으로 동작하는 것 같다. 왜냐하면, Array의 Index가 연속하지 않아도 동작한다. 그저 Key가 0 이상의 정수인 Map이랑 비슷하게 동작한다. 예) 1, 2, 3, 9, 10 Array # 생성 declare -a empty_array declare -a ar=(haha hoho baba "long string haha hoho") # 접근 echo "ar[0]=${ar[0]}" echo "all as array=${ar[@]}" # 큰따옴표 안에서 각 원소를 따로따로 전달한다. echo "all as one=${ar[*]}" # 큰따옴표 안에서 각 원소를 문자열 하나로 합쳐 전달한다. echo "indexes=${!ar[@]}" echo "indexes=${!ar[*]}" echo "length=${#ar[@]}" echo "length=${#ar[*]}" echo "last=${ar[-1]}" echo "last=${ar[@]: -1}" # 콜론 뒤에 빈 칸이 꼭 필요하다. 옛 방식 # 현재 상황 declare -p ar #(출력) declare -a ar=([0]="haha" [1]="hoho" [2]="baba" [3]="long string haha hoho") ar[100]=hello # 인덱스를 건너 뛰어도 동작한다. declare -p ar #(출력) declare -a ar=([0]="haha" [1]="hoho" [2]="baba" [3]=&

Linux에서 find결과를 시간 순서대로 정렬하기

때때로 어떤 디렉토리 내용을 수정시간 순서(보통 역순)대로 정렬할 필요가 있다. 그럴 때 사용할 수 있는 옵션이 -printf 옵션이다. %T+는 마지막 수정시간을 YYYY-MM-DD+HH:MM:SS.ssssssssss 형태로 출력한다. 참조: https://man7.org/linux/man-pages/man1/find.1.html find /path/something/ -mindepth 1 -maxdepth 1 -type d \ -name 'myapp-*' -printf "%T+\t%p\n" | \ sort -r | awk -F'\t' '{print $2}'