파라미터 중 앞 몇 개를 체크 후 나머지를 전달하고 싶을 때 shift 로 제거 후 $@ 으로 전달하면 된다.

function build() {
    echo "build with $@"
}

echo "Starting args are $@"
cmd=$1
shift

if [ "$cmd" = 'build' ]; then
    build "$@"
fi

출처 : https://stackoverflow.com/questions/12002954/bourne-shell-send-arguments-2-to-n-to-variadic-function

728x90

aws 콘솔에 모니터링 페이지가 있지만 cpu 최적화할 때 측정용으로는 애매한 것 같다.

top -b

다양한 cpu 모니터링 툴이 있지만 top 이 무난하고 좋은 것 같다. top 은 화면으로 출력되는 콘솔 모니터링 프로그램인데 파일로 저장하려면 배치 모드(-b)를 이용해야 한다. 간격은 -d 옵션을 이용하면 된다.

-b : Batch mode operation

Starts top in 'Batch mode', which could be useful for sending output from top to other programs or to a file. In this mode, top will not accept input and runs until the iterations limit you've set with the '-n' command-line option or until killed.

-d : Delay time interval as: -d ss.tt (seconds.tenths)

Specifies the delay between screen updates, and overrides the corresponding value in one's personal configuration file or the startup default. Later this can be changed with the 'd' or 's' interactive commands.

Fractional seconds are honored, but a negative number is not allowed. In all cases, however, such changes are prohibited if top is running in 'Secure mode', except for root (unless the 's' command-line option was used). For additional information on 'Secure mode' see topic 5a. SYSTEM Configuration File.

ex) top -b -d 30

: 30초 간격으로 출력

참고 :

https://linux.die.net/man/1/top

https://www.tecmint.com/save-top-command-output-to-a-file/

grep -A

기본으로는 모든 프로세스가 cpu 사용량 별로 소팅되어 보이는데 사실 상위 n 개만 관심이 있다. 이럴 때는 grep -A 옵션을 이용해서 "load average"가 매치되는 줄에서 n 라인을 가져오도록 한다.

ex) top -d 5 -b | grep "load average" -A 15
: 5초 간격으로 출력된 결과물 중 "load average" 아래 15개 줄을 가져온다.

참고 : 

tee

결과를 리디렉터(>)를 이용해서 파일로 저장할 수 있지만 화면으로 확인하고 싶다면 tee 를 이용하자.

ex) top -d 5 -b | grep "load average" -A 15 | tee cpu_us.log
: 5초 마다 cpu 사용량 상위 10개 프로세스를 cpu_us.log 파일로 저장

grep --line-buffered

하지만 화면에 뭔가 이상하게 출력되고 파일로 저장된다. 파이프( | ) 나 리디렉터( > ) 문제인 줄 알았는데 각각의 프로그램이 원인이라고 한다. grep 옵션을 보니 --line-buffered 를 이용하면 라인단위 처리를 해서 성능이 떨어진다고 하는데 이 옵션을 사용하고 문제가 해결되었다.

       --line-buffered
              Use  line  buffering  on  output.   This can cause a performance
              penalty.

ex) top -d 5 -b | grep "load average" -A 15 --line-buffered | tee cpu_us.log

참고 : 


728x90

svn 1.10 에 shelve 가 추가되었다.

shelve 는 WC 에 작업중인 코드가 있는데 특정 버그를 수정해야할 때 새로 체크아웃받지 않고 작업할 때 유용한 것 같다.

: 로컬에 작업중이던 코드를 shelve 를 통해 올려놓고 WC 를 rollback 한다.
: 버그를 수정한다.
: 수정된 코드를 커밋한다.
: unshelve 를 통해 작업중이던 코드를 다시 적용한다.

svn 1.11 에는 checkpoint 라는 기능이 작업 중인데 얘는 git 의 local commit 비슷한 동작을 지원하는 것 같다.

이제 파일 개수와 버전이 올라감에 따라 느려지는 속도만 Perforce 수준으로 빨라졌으면 한다.

출처 : https://cwiki.apache.org/confluence/display/SVN/Shelving+and+Checkpointing+Dev

728x90

사이트 차단 때문에 말이 많았는데 vpn 도 있고 해서 실효성이 있나 모르겠다. 그 때 Goodbye DPI 라는 프로그램을 알게되었는데 사용하기도 편하고 무료라 PC 에서 사용하기에는 최고인 것 같다.

GoodbyeDPI 사이트에서 0.1.5 버전을 다운 받은 후 압축을 풀고 64비트 OS 의 경우 x86_64 폴더에 있는 goodbyedpi.exe 를 실행하기만 하면 된다.

다운로드 : https://github.com/ValdikSS/GoodbyeDPI/releases

참고 : https://www.clien.net/service/board/park/13153189

이번 기회에 성인 대상 야동 유통 합법화나 논의 되었으면 좋겠지만 기독 유교 탈레반 국가에서 논의가 시작될 수나 있을지 모르겠다.

728x90

C3859 계속 PCH에 대한 가상 메모리를 만들지 못했습니다.

가끔 프로젝트나 엔진 코드를 빌드하다 보면 C3859 오류가 발생할 때가 있다. -Zm146 옵션을 추가하라는 컴파일러 안내가 있었다. 하지만 언리얼은 VCToolChain 에서 /Zm850 이 기본으로 훨씬 많은 양을 추가하고 있는 상태였다.

코드에는 있지만 정말 /Zm850 옵션이 적용되는지 의심스러워서 확인해보았다. IncrediBuild 를 사용하고 있어서 엔진 설치 경로에서 Intermediate/Build/XGETasks.xml 을 확인했다.

Tools > Tool Element 에 Params 로 실제 cl 에 넘어가는 파일 경로를 확인할 수 있다. '파일명.cpp.obj.response' 형식이다. 파일을 열어서 확인해 보니 /Zm850 옵션이 적용되어 있었다.

혹시 실패가 특정 PC 에서 발생하고 있는지 확인해보니 특정 PC 에서 발생하고 있었다. IncrediBuild Coordinator 로 column 에 Environment > Virtual Memory 를 확인해보니 Avail 용량이 800MB 정도 밖에 안되는 PC 였다. 실제 가상 메모리가 부족한 상황이었다. -ㅁ-

몇 일간 빌드 옵션 문제 인가 싶어서 옵션을 바꿔가며 삽질했는데 현실은 환경 문제였다. :(

728x90

변수가 특정 문자열을 포함하고 있는지에 따라 분기처리를 해야할 경우가 있다. find 나 findstr 의 errorlevel 을 이용해서 처리하면 된다.

set TestStr=imit@imitursa

echo %TestStr% | find "@imitursa" >nul

if errorlevel 1 (echo notfound) else (echo found)


출처 : https://stackoverflow.com/questions/34077831/how-to-see-if-a-string-contains-a-substring-using-batch/34077870#34077870

728x90

OnlineSystemNull 을 데디 서버에서 사용하는 경우 OnlineAsyncTaskThreadNull 이 돌고 있는데 코드에서 사용하는 곳이 없었다. 엔진 코드를 뜯어 고쳐서 Thread 가 생성되지 않게 할 수도 있지만 설정만으로 cpu 를 덜 사용하게 할 수는 있다.

// FOnlineAsyncTaskManager::Run

do 
{
// Wait for a trigger event to start work
WorkEvent->Wait(PollingInterval);
if (!bRequestingExit)
{
Tick();
}
}

OnlineAsyncTaskThreadNull 은 PollingInterval 마다 sleep 하는 구조다. PollingInterval 의 기본값은 50ms 인데 -1(INFINITI) 값을 주면 Queue 에 작업을 줄 때 까지 Sleep 시킬 수 있다.

// FOnlineAsyncTaskManager::Init

if (GConfig->GetInt(TEXT("OnlineSubsystem"), TEXT("PollingIntervalInMs"), PollingConfig, GEngineIni))
{
PollingInterval = (uint32)PollingConfig;
}

초기화 코드를 보면 Engine.ini 에서 설정 가능하다.

[OnlineSubsystem]
PollingIntervalMs=-1

위와 같은 섹션을 추가 혹은 수정하면 된다. PollingIntervalMs 는 int 로 읽어서 unsigned int 로 변환된다.

728x90

학교 졸업하고는 linux 를 써본 적이 없으니 얼마만에 써보는 지 모르겠다. if 문에서 계속 오류가 발생해서 뭔가 싶었는데 공백 문제였다. 

if [ conditions ]

if 다음에 공백 있고 '[', ']' 와 조건 사이에도 공백이 반드시 있어야 하네 -ㅁ-

출처 : https://stackoverflow.com/questions/16034749/if-elif-else-statement-issues-in-bash

728x90

UE4 에서 RPC가 구현된 class 는 Actor 와 ActorComponent 로 보입니다. Actor 의 멤버로 UObject 를 상속받은 class 는 RPC 함수들이 있어도 동작하지 않습니다. 

UObject 를 상속받은 클래스에는 IsSupportedForNetworking, IsNameStableForNetworking, CallRemoteFunction, GetFunctionCallspace 구현이 필요합니다.

cf. Outer class 가 APlayerController 라고 가정합니다. 통신이 가능한 Actor 면 상관없습니다.

class UMyObject : public UObject
{

virtual bool IsSupportedForNetworking() const override
{
return true;
}

virtual bool IsNameStableForNetworking() const override
{
return true;
}

virtual bool CallRemoteFunction(UFunction* Function, void* Parameters, FOutParmRec* OutParms, FFrame* Stack) override
{

if (auto MyOwner = GetOuterAPlayerController())
{
UNetDriver* NetDriver = MyOwner->GetNetDriver();
if (NetDriver)
{
NetDriver->ProcessRemoteFunction(MyOwner, Function, Parameters, OutParms, Stack, this);
return true;
}
}
return false;
}

virtual int32 GetFunctionCallspace(UFunction* Function, void* Parameters, FFrame* Stack) override
{
auto MyOwner = GetOuterAPlayerController();
return (MyOwner ? MyOwner->GetFunctionCallspace(Function, Parameters, Stack) : FunctionCallspace::Local);
}

} // UMyObject

추가로 Actor 의 Subobject 는 1단계만 허용되는 것 같습니다.

참고 : https://answers.unrealengine.com/questions/435733/rpc-doesnt-work-on-repicated-uobject.html


728x90

git 을 오랜만에 사용하는데 아래와 같은 오류 메시지가 발생했다.

remote: HTTP Basic: Access denied
fatal: Authentication failed for 'https://gitlab.com/myname/myproject'

전에 git 명령어로 설정한 데이터가 문제를 일으키는 상황같아 보였다. TortoiseGit 에서 Authentication data 를 Clear 해서는 초기화되지 않았다.

인증 관련 데이터를 초기화하기 위해서는 아래와 같이 처리하면 된다.

  • 관리자 권한으로 명령창을 연다.
  • 'git config --system --unset credential.helper' 를 실행한다.
  • global 영역 설정이 문제를 일으킬 수 있으니 'git config --global --unset credential.helper' 를 실행한다. 

출처 : https://stackoverflow.com/questions/47860772/gitlab-remote-http-basic-access-denied-and-fatal-authentication

(2020-08-25)

git 로그인에 사용한 아이디/패스워드가 오래되서 발생한 문제라면 아래와 같이 기존 데이터를 삭제하면 된다.

윈도우 명령창(윈도우 + R) 에서 아래 명령어를 입력해서 '저장된 사용자 이름 및 암호' 창을 띄운다.

rundll32.exe keymgr.dll,KRShowKeyMgr

git 으로 시작하는 아이템을 선택해서 제거하고 다시 시도해보자.

728x90

+ Recent posts