옵션 |
|
안녕하세요. 오유 독자님들.
오전에 집앞에 병원가느라 오늘 조금 늦었습니다. 죄송합니다.
오늘도 즐거운 하루 되시고, 즐감 부탁드립니다.
(오늘 글에도 됬이 보여 됐으로 고칩니다. ㅋㅋㅋ)
---------------------------------------------------------------------------
나: 음..특정 불량 좌표가 아니라 전체적인 불량점들의 좌표가 다 밀리나요?
로보트: 넵.
과거 처음 이 문제를 맞닥 드렸을때 멘붕이 왔었음. 도대체 콩과장이 있을 때는 조용하더니
왜 내가 코드를 받으니까 모든 문제들이 수면 위로 떠오르는가!!!!!
이것들이 다 짜고 나를 내 치려고 하는 것인가!!!
용서 할 수 없다!!!!! 호카게!!! 목사님!! 콩과장!!! 다 죽었어!!!!!
열폭 했었음.
검사 스타트를 진행 할 경우, 이 롤장비에는 로터리 타입이라는 둥그런 엔코더가 달림.
그게 롤과 맞물리며 회전을 하는데, 이 모듈은 회전을 하며 그 진행 거리를 측정할 수 있는 기기임.
일정 량의 회전마다 전기적 펄스가 올라오고. 그걸 카운터보드라는 모듈에서는 1펄스당 1mm, 5mm 이런식으로
값을 카운팅 해줌. 즉 1펄스에 5mm라면 20펄스라면 100mm를 진행했다 라고 보면 됨.
번뜩 떠오르던 추측.
그렇다면 최초 시작 순간이 중요한데. 모종의 이유로 프로그램이 시작 시에 저 엔코더 값을
불규칙하게 놓치고 Zero에서 시작한다는 느낌. 그 놓친 펄스 만큼의 좌표가 오차 나는것이 아닐까..?
본인이 기억하기로는 콩과장의 코드라면 최초 시작 시
여러 데이터 정리와 광학계들의 연결상태 체크, 아이오 체크 같은 일련의 체킹 과정을 거친 후
검사 스타트가 발생함. 걔 중에서 좀 마음에 안드는...눈에 거슬리던 코드가 하나 있었음.
그건 바로 Wait() 코드였음.
----------------------------------------------------------------
콩과장의 코드... 설명을 조금 달자면
void Wait(DWORD dwT)
{
DWORD dwST = GetTickCount(); -> 이 명령문의 이 순간의 시간이 캡쳐가됨.
DWORD val = GetTickCount() - dwST; -> 여기서 다시 GetTickCount() 가 나오는데 이전의 시간이 A라면 지금 이순간 다시 캡쳐한 이 시간은 B인거임.
결국 val 이라는 변수에는 B시간 - A시간. 즉, B 와 A 의 시간차가 들어간다고 보면됨. 분명 0에 가까운 시간이 들어갈거임.
while( val < dwT) -> 우리가 Wait(10) 이라고 이 함수를 구동시켰다면 dwT에는 10이라는 숫자가 들어가겠지.
당연히 val 값은 10보다 작을테니 while 이라는 반복문이 동작 할거임.
이 val 이라는 값이 dwT의 값과 같거나 커진다면 이 반복문은 종료가 되는 거임.
{
val = GetTickCount()-dwST; -> 여기서 실행된 GetTickCount()는 위의 A, B와는 또다른 C라는 시간임. 매번 반복될 때 마다 D, E, F 시간으로 갱신되겠지.
결국 최초 시작시간 dwT라는 변수와의 시간차가 val 변수에 들어가는 것이고 그 값이 dwT를 벗어나면 break를 만나 반복문을
빠져나가는것. ㅋㅋ
if(val >= dwT) break; -> 근데....어차피 반복문의 조건이 있는데 if(val >= dwT) break; 이 코드가 필요가 있는가!?
이것이 바로 장비업계 코드란거임. 콩과장의 이 판단에 대한 설명은 밑에있는 코드를 보며 설명하겠음.
HandleAllMessage(); -> 요놈
Sleep(0);
}
}
int HandleAllMessage()
{
int returnValue;
MSG Mess;
do
{
returnValue=::PeekMessage(&Mess, NULL,0,0, PM_REMOVE); -> 현재 프로그램의 메세지 큐에 값이 있는지 확인 하는 코드. 값이 있다면 1을 반환함.
if(returnValue) -> 메세지가 존재한다면 수행되는 조건문
{
::TranslateMessage(&Mess);
::DispatchMessage (&Mess);
->메세지 큐에 메세지가 있다면 얼른 해당 메세지를 처리하고 비우라는 뜻임.
}
Sleep(0);
}while(returnValue); // 메세지 큐에 메세지가 없는 상태. 0 가 되면 이 반복문은 끝이남.
return returnValue;
}
----------------------------------------------------------------------------------------------------------------------------
정리하자면 HandleAllMessage() 라는 함수는 메세지 큐에 메세지가 있으면
후딱후딱 쫘악~~~처리해서 메세지 큐를 비워버리는 함수임.
그럼 다시 if(val >= dwT) break; 코드는 왜 불필요하게 존재하고 있는가?
이론적으로 본다면 이미 while( val < dwT) 이라는 조건으로 인해 불필요한 코드가 될 것인데.
그것은 '한 타이밍' 더 빠르게 만들기 위한 콩과장의 판단 임.
어쨌든 저 break를 만난다면 HandleAllMessage()를 한번 덜 수행 할 수 있는거임. 장비업계의 욕심^^
그렇다고 그를 비웃을 순 없음. 0과 1은 큰 차이는 없으나 그 차이는 분명이 존재하는 것이기에..!
섯불리 지웠다가는 곤욕을 치를 수 있음.
시니어의 주화입마라는건 이런 '방심'에서 발생함.
그냥 맘에 안들면 막 지워버리면서 일하는거지... 그러다 코드를 돌렸는데 기존 장비보다 더 미쳐 돌아가는...ㅋㅋ
어쨌든...이 것이 그의 Wait 코드였음.
대만 프로젝트를 하던 사원 시절에 회사 코드에서 자주 저 Wait 함수를 보았음.
당시의 의문은 Sleep과 Wait의 차이가 무엇인가?
그리고 회사내 과장들 혹은 메가통 팀장에게 질문을 해 보았는데
어떤 사람들은 똑같다 였고, 어떤 사람들은 니가 알아서 해.
헬과장의 경우는 한숨을 푹~~ 쉬며
'이게 당신의 수준이에요.'
라며 핀잔을 주었음. 그러기에 자존심이 상한 본인은 이 부분에서 상당히 민감한 트라우마가 있는 코드였음.
Sleep(10)과 Wait(10)의 차이는 무엇인가?
쉽게 설명하자면 Sleep(10)은 딱 10msec 동안 내 프로그램이 잠을 자는거임.
꿈도 안꾸는 개꿀잠을 잔다는 거임. 멈추는거지.
Wait(10)은?? 몽유병 상태? ㅋㅋ 그것보다는 반만 잠을 자는거임. 잠은 자되 꿈을 꾼다고 해야하나?
오히려 햇갈리는 설명인듯...;; 정리하자면 Sleep 은 진짜 완전히 모든 동작이 멈춤.
Wait은 코드 설명과 같이 당장의 프로그램의 플로우(흐름)은 멈춤 상태이지만 메세지큐를 열심히 비우고있는 상태임.
10msec라는 짧은 시간이라면 별 차이가 없겠지만 만약 이것이 2000msec(2초)가 된다면 사용자의 눈에 확연히 드러남.
Sleep(2000)의 경우 사용자가 프로그램 화면상에 마우스를 움직이거나 클릭하면 모래시계가 빙글빙글 돌며. 그 상태로
이것저것 클릭을 할 경우 아무런 동작을 하지 않음. 타이밍 나쁘면 그대로 에러창이 땡~ 뜨면서 프로그램이 죽음.
Wait(2000)의 경우 사용자가 마우스로 이런저런 동작을 해도 이것저것 잘 동작함. Wait이 걸린지도 모르는거임.
왜냐. Wait 상태에서는 열심히 사용자가 움직이는 마우스 이벤트를 처리하고 있는 상태니까.
그렇기에 프로그래머는 Sleep과 Wait의 특성을 알고 적절한 방식을 '판단' 해야함.
콩과장은 Wait을 선호하는 개발자였음. 그의 코드에는 Sleep은 거의 없고 Wait을 대부분 사용했음.
여기서 그의 심리를 느낄 수 있던게. 전공정 장비는 가동중에 죽으면 난리가 나는 설비 아니겠음?
콩과장은 만일에 Sleep을 넣었다가 프로그램이 죽는 상황이 두려웠던 거임.
그럼에도 플로우는 잡아둘 필요가 있고, 장비가 뻗는 상황은 피하고 싶은 마음이 수 많은 Wait 코드로 드러나는것.
본인도 전공정을 하던 시기에 Sleep과 Wait의 특성 정도는 당연히 알고있었음.
그러나 정말 한끗 차이에서 프로그래머의 퍼포먼스는 달라지는것 같음.
Sleep(100) 이라면 분명 100msec와 거의 일치한 시간이 나옴.
그러나 Wait(100)이라면 분명 메세지 큐를 비우는 과정이 빈번하게 일어나기 때문에,
만약 메세지가 특이한 타이밍에 많이 발생하게 된다면 분명 그것을 처리하는 시간이 조금 추가 되는거임.
즉, 100msec가 100이 아니게 되는거임. 타이밍의 엇나감을 발생 시킬 위험성이 존재하는 코드.
그럼 이벤트가 무지막지하게 늘어나는 장비 타이밍이 언제인가?
그건바로 최초 프로그램 스타트 순간임. 카메라들의 연결을 확인하면서 발생되는 이벤트.
스타트 버튼을 누르는 순간이라면 사용자의 손에는 마우스가 쥐어져 있다는 것이고. 마우스 이벤트는 실시간으로
Move 이벤트를 엄청나게 뿌리고 있을 테니까. 그외 체킹 과정들 역시 이벤트가 발생하는 파트들이 존재했음.
***
그런 과거 생각을 하며 지금 로보트 주임이 얘기하고 있는 장비의 좌표 밀림 현상을 듣고 있었음.
이 부분을 대리들에게 말을 해 줘야 하나...? 잠깐의 고민.
그러나 말하지 않았음. 사람의 감정이란....
솔직히 괘씸했음. 나는 전공정을 떠나던 시절 분명히 잇끄 대리에게 내 마지막 대공사한 프로젝트를 남겼음.
후임자들이 더이상 쫓겨나는 일이 없도록, 당시 내 역량 모두를 쏟아부어 정리된 코드를 남겼음.
그런데 이 장비에 적용된 코드는 내가 남긴 코드가 아니었음.
잇끄 대리는 정리된 내 코드를 보고 전공정의 원리를 파악한 뒤, 실제 사용은 콩과장의 코드를 써왔던것.
왜냐고? 본인의 코드는 깔끔하게 정리 된 만큼 컨셉에 맞춰서 새로 기능을 구현해야 함.
콩과장은 코드가 매우 더럽지만 필요 기능들이 모두 구현되어 있음.
[잇끄 대리는 귀찮았던 거임.]
그저 객관적인 눈으로 보고, 어떤것이 더 나은가 판단하기 보다
구현하기 귀찮고 당연히 과장이 더 낫겠지~ 해버리는거임.
결국 내 모든 노력은 허사가 되었고, 새로나온 전공정 장비들은 악순환의 고리를 끊어내지 못했음.
그래...그러니까 지금껏 RPM이 안나왔던 거겠지....
[이건 너네들이 자초한 결과다....]
지나간 상념들이 떠올랐음.
왜 초장부터 이 대리 형들은 우리와 같이 뭉치려 하지 않고, 우리(나, 창희)와 벽을 쌓았는가?
눈앞에 보이는데도 고개 돌려 외면하고, 인정해 주지 않았는가? 그러면서도 어려움이 생기면
굳이 우리에게 도움을 받아갔던가?. 그게 꼭 대단한 부분의 도움을 받아 간건 아닐지라도....
대부분 사소한 실수...
아마 그래서 일까...도움을 주고도 어떤 감사를 받는 느낌을 못느꼈음.
아까 언급하지 않았음? 한 끗 차이로 프로그래머의 퍼포먼스가 달라진다고.
대부분의 사람들은 그 '한 끗' 이라는 차이에 의미를 두지 않았고
'아~ 이정도면 굳이 니가 아니라도 시간만 좀 더 지났다면 내 스스로도 알았을 거야~'
'고작 이거 알려 줬다고 설마 도움을 줬다고 착각 하는건 아니겠지?'
하는 자기 최면을 걸게됨. 그 이유는 동생들 보다 못나고 싶지 않다는 자기방어.
이 대한민국에만 존재하는 '형님' 문화....
정말 애매한 문화임. 실제로 학연이나 지연으로 얽힌 관계라면 모르겠음.
중학교 선배와 본인의 관계속에서 본인은 '이유 없는' 친절과, 이유없이 든든한 아군을 얻었으니까.
이 부분은 무시할 수 없다고 하겠음.
반면, 단순히 사회에서 만났는데, 그 놈의 형님 문화라니...
본인은 사회에서 만난 어린 동생들에게 따로 형님 대접 같은건 바라지 않음.
왜? 이유는 스스로에게 물어보면 됨.
1. 내가 살아가면서 이 사람에게 10원한푼 보태준적이 있는 사람인가?
>>아니. 이번에 첨 본 사람임. 남남.
2. 내가 이 사람을 위해 '연장자'로서 챙겨주고, 무언가를 먼저 감내 할 생각이 있는가?
>>아니. 사회생활에 그런게 어딨나? 뭐 정말 괜찮은 사람이면 생각은 해보는정도..?
3. 내가 이 사람에게 '형님' 소리 들으면 대단히 자존감이 높아지는가?
>>아니. 내 자존감은 그런데서 오는게 아니다.
4. 그럼 이 사람이 나를 만만하게 보고 무시하면 어떤가?
>> 그건 위든 아래든, 동갑이든 관계없이 까부숴야 될 문제다. 나이와는 관계없다.
5. 이 사람이 나보다 뭐든 뛰어나다는 사실에 배가 아프지 않은가?
>> 그럴거면 차라리 빌게이츠나 이재용을 보고 배가 아픈게 낫다. 손이 닿지 않는 자들이 아닌
내 손이 닿는 거리에 있다는 거니까. 가까이 하고 옆에서 보고 배우는 편이 훨씬 낫다.
이 생각을 곰곰히 해보면 내가 그들에게 '형님' 소리 듣고,
양보 받고 대접받을 하등의 이유가 없음.
그랬기에 1살어린 무쌍이와 좋은 관계를 맺어갈 수 있었던거 같음.
나보다 1살이 어리던 5살이 어리던 무쌍이가 대단하다는건 부정할 수 없는 사실이었으니까.
그러나 의외로 다른 사람들은 자기 객관화가 안되어 있음. 자기 최면에 빠져있는 상태라고 할까?
자신보다 뛰어난 '어린' 친구를 받아들이지 못함.
그렇다면 차라리 자기가 무조건 낫다고 완벽하게 자기 최면을 걸어야 하는데.
정신승리는 하되, 그 대상을 경계하고 경원시 하게 됨.
이래서 사람이 동물과 다르게 영악 하다고 하는걸까?
그리고 그 영악한 집단들끼리 단단한 결속으로 뭉치게 되고.
도움을 준 사람은 '모난 돌', 외톨이가 되어버림.
도와준 입장에서는 득은 없고 '실'만 얻게 되는것. 그런 심리를 경험적으로 체득하고 있기에.
그리고 사람을 바라보는 '눈'에 있어. 지금껏 누구보다 정확했기에.
잇끄 대리와 카푸어 대리는 '그릇'이 부족했음.
동생인 우리에게 배려를 받을 자격이 없다...
***
나: 혹시 또 해결 안된 문제는 없나요?
로보트: 그게...제일 골치아픈게 하나 있는데...예전 팀장님 전공정 하실 때 말이에요...3호기에..
나: 설마...3번 광학군 검사 프로그램 뻗는거....? 아니죠..? 몇년이 지났는데...;;
로보트: 맞습니다..몇년이 지났지만...개선이 안된.....
[잇끄 형....뭐하고 있던거야......]
아...이거 때문에 전공정은 조용할 수 밖에 없었구나...
이 문제는 완전 높은 과속 방지턱이였음. 차체가 낮은 스포츠 카로는 가히 넘지 못하는...
바닥을 제대로 긁을 각오를 해야하는 그런 방지턱.
이상하게 코드는 거의 동일했음. 그게 AI가 추가되며 동일한 코드에서 문제가 발생하는것.
그렇다고 AI가 직접적으로 뻗는 문제에 연관이 있는가 하면 그게 아니라는게 더 골치가 아픈 문제였음.
큰 마음먹고, 출혈을 각오하며 디버깅을 진행한 적이 있는데.
분명 죽는 위치는 화살표가 걸려 나왔음.
그럼에도 불구하고 도저히 말이 안되는 결과에 '엥~~!?' 하게 되는.
전혀 죽을 위치가 아닌 곳에 걸려있는 디버깅 플로우..
당시 본인은 일단 답이없으니 다음 문제로 패스~~~ 하고 넘어갔고.
최 후순위로 언젠간 내가 잡겠다! 하며 남겨둔 문제였음.
원래라면 전공정 최후의 프로젝트를 깔끔히 마무리 한 뒤,
생기는 여유시간동안 제대로 잡고 연구해 보려고 했었으나..
지박령 과장과의 싸움으로 인해 퇴출이 되었으니...
이 부분 최우선 적으로 잇끄 대리에게 전달하고 미안함을 전했음. 잘 좀 부탁한다고.
그동안 조사하던 데이터들도 다 전달했고. 걱정 말라고 하더니....
지금 몇년이 지났는데 아직...회사에 보고도 없이..
이 문제로 인해 3호기 장비는 더이상의 새로운 업데이트가 불가능 해졌음.
이 문제를 해결해야 3호기라는 장비의 신규 업데이트라는 과제가 완성되기에...
마치 잘 굴러가는 새차에 앞바퀴가 하나 빠져있는거임.
바퀴를 달아줘야 달릴 수 있는데, 바퀴를 아무리 찾아봐도 안보여서 제대로 굴리지도 못한채 몇년을 방치한 상태..
[목사님이 전화 할 만 하다...몇년간 정말 오래도 참았다....]
아마도 목사님 역시 본인과의 싸움에서 느끼는 바가 컷던거 같음.
협력업체 직원들을 다루는 태도에 있어서 예전 같지 않았음. 예전 같았으면 벌써....어휴..;;
나: 과거에 제가 못한 일이니. 다시한번 해 보겠습니다. 이제 몇년 지났는데.
그때의 저 보다는 지금의 제가 더 나을거라 믿습니다. ㅎㅎ 쉬지않고 달려왔으니까요^^
로보트: 오..!! 저도 이번엔 꼭 찾아내 실거라 믿습니다 팀장님!!
나: 그럼 오늘은 이만 퇴근하고, 원래는 내일 나와볼 생각이었는데.
이 문제는 일단 본사에서 차분히 알아보고 처리하는게 편할거 같아요.
로보트: 네네! 상관없습니다. 그렇게 하시죠!
***
그렇게 잇끄, 카푸어, 본인은 퇴근길에 올랐음.
나: 대리님들 오늘 새로 업데이트 된 사항 있습니까?
대리들: .......1개 항목 쳐 내긴 했는데........
나: 오~ 그래도 성과가 없진 않네요. (음..19개 남았군)
대리들: OO씨는 어때요?
나: 아. 저도 후순위 항목들 몇가지 처리 했습니다. 이번 주까지 일하고 정리해서 공유하면 되겠네요^^
대리들: 네 알겠습니다.
나: 저는 이번에 3호기 검사프로그램 뻗는 문제 해보려고 하는데. 괜찮으시죠?
잇끄: 아...그거요...;; 어차피 저희는 못고치던 거라...상관없습니다...
나: 그럼 저는 내일은 본사에서 코드 분석좀 할건데, 나머지 분들은 어떻게 하실래요?
대리들: 저희는 내일도 나와서 현장진행 하겠습니다.
나: 네^^
***
다음날 이른 아침부터 전공정 코드를 열어보았음.
찬찬히 전반적인 프로그램 동작들을 머리속에 그려보며 마치 내가 검사 장비가 된듯
눈을 감고 검사 진행하는 상상을 했음.
프로그램이 뻗는데는 단 한가지 상황만이 존재했음. 그건바로 테이프가 지나가는 시점이었음.
이 테이프를 이O매 라고 하는데. A라는 Roll 필름과 B라는 Roll 필름을 연속 생산할 시, A와 B 사이에 테이프를 붙여
연결을 함. 일종의 제품 구분선이 되었다고 보는게 맞음.
그게 검사진행 중에, 테이프 센서를 만나게 되면 프로그램은 로트 정리를 진행함.
A라는 제품의 끝을 알리는 동시에 B라는 제품의 시작을 알리는 신호의 의미이기에 A로트 데이터 정리 및 B로트 데이터의 시작을
프로그램이 자동 진행하는 방식이었음.
로트 정리라는건 방대한 데이터의 처리였음. 2500M나 되는 롤 필름에 불량이 얼마나 많겠음?
최소 2만개에서 4만개, 많으면 7만개 까지 있음.
이 엄청난 데이터를 서버 프로그램이 이미지부터 좌표 데이터까지 싹다 가지고 가는 작업이니...
물론 Thread의 분리로 인해 해당 작업을 Thread A가 진행하는 동안 Thread B는 정상적인 검사 동작을 진행함.
여기까진 문제가 없고. 결국 죽는 현상은 검사 프로그램에서 벌어지기에...
검사 프로그램의 입장에서는 서버 프로그램과는 좀 다름.
Thread를 너무 많이 분리한다는건 퍼포먼스의 저하로 생각하면 됨.
드래곤볼에서 손오공과 천진반의 천하제일 무술대회를 생각해보면...
천진반은 4명으로 분신을 나누어 전투를 했음. 그리고 떡발림.
천진반: 왜지!? 내 전술은 완벽 했을텐데?
손오공: 4명으로 분리한건 분명 효과적이었어. 하지만 네 실수야.
한 사람의 능력을 넷으로 나누었으니 힘도, 스피드도 모두 4분의 1이 된 셈이니까..!
프로그램도 마찬가지임. 물론 Thread라는 개념을 단순히 이렇게만 보면 안됨. 결국은 어떻게 사용하느냐 이기에.
병렬 처리의 경우 2초가 걸릴 업무를 500msec에 끝낼 수 도 있음.
지금 언급하는 Thread는 병렬처리가 아니라는걸 유념 하시면 될듯.
셀과 손오반의 최후의 에네르기파 대결이 바로 병렬처리임. 죽은 손오공이 슬쩍 장풍 싸움에 끼어들어
손오공: 오반...힘을내라..! 이익....!? 이때다~~~~앗!!!
손오반: 으아아아압~~~!!!!!
한개의 Thread가 일을 하다가 기회를 봐서 이때다 싶으면
4개로 쪼개서 순식간에 나눠서 일을 해버리고 다시 하나로 돌아가는거임.
실제로 손오공의 힘이 보태져서 셀을 이긴거라고 생각하지 않음.
손오반은 아버지의 조언을 받아 순간적으로 오른팔에 파워 RPM을 올린거임.
어쨌든 검사 프로그램은 천진반의 케이스 임.
메인 Thread와 검사 Thread 외에 서버 프로그램 처럼 기타 따로 돌고있는 Thread를 가급적 많이 나누어 돌리지 않음.
여기서 차이가 하나 발생하게 됨. 구 프로그램과 신 프로그램의 차이. 바로 AI Thread가 추가 되어 있는것.
이는 확신할 순 없지만. 천진반이 한명 더 쪼개진 상황이었음.
새로 추가된 천진반은 실시간으로 Ai 판정난 데이터를 서버로 전달하는 역할을 하기에
계속 돌며 전반적인 프로그램 퍼포먼스를 나눠먹고 있는것.
그렇다면 1, 2, 4군 프로그램은 죽지 않는데... 왜 하필 3군 프로그램만 테이프가 지나갈 경우 뻗는 것인가...?
테이프가 지나간다는건 결국 검사 카메라를 지나간다는 뜻이고.
서버가 로트를 어떻게 정리하든 간에, 검사 프로그램은 일단 눈에 보이는
놈은 검사를 하고 봄. 그걸 서버에서 불필요한 영역의 검사 데이터는 삭제처리 하는 방식.
이 상황의 키워드를 정리해 보았음.
1. 또 한명의 천진반 추가 = 이전 프로그램 버전보다 퍼포먼스의 미세한 저하.
2. 테이프에 대한 검사 -> 이 순간 뻗음.
3. AI 시스템이 도입되고 발생(무언가 연관이 있을 법한....)
이 두개의 키워드를 가지고 3번 광학군의 검사 알고리즘을 뜯어보기 시작했음.
그러자 상상이 되는 이 코드의 동작. 3번 광학군은 '기포'를 검사하는 알고리즘 이었음.
테이프가 지나가면 1, 2, 4 광학군의 특성상 어두운색의 불량을 잡아내는 것이라 테이프에서
많은 불량점이 검출 되진 않음.
문제는 3번 광학군. 기포 검사였음. 기포는 밝은색의 불량을 잡아내는 것이기에
테이프가 지나가는 경우 3번 광학군은 하는일이 매우 많아진다는 것.
AI Thread 역시 그만큼 하는 일이 많아지는 것이고. 그 찰나의 퍼포먼스 지연 시간동안
오류를 일으킬 만한. 즉, 치명적으로 프로그램을 죽일 수 있을 만한 데이터가 있는지 찾아보았음.
그리고 해당 부분에서 문제를 일으킬 만한 데이터는 현재 이미지의 frame 넘버였음.
AI 데이터는 자신의 판정 정보에 현 이미지의 frame 넘버를 키 값으로 가지고 데이터를 서버로 전송했음.
만약 이 키 값이 변하면 기존에 담고있던 AI 데이터는 날아감.(비워짐)
시퀀스를 머릿속에 정리해 보았음.
(테이프) 이미지 촬영 -> 엄청난 기포 감지 및 검출(검사) -> AI 데이터 처리 -> 완료
이미지 촬영 -> 검사 -> AI 데이터 처리 -> 완료 -> 이미지 촬영 -> 검사 -> AI 데이터 처리 -> 완료.....
거기서 드는 한가지 추측.
만약 퍼포먼스의 저하로...정상적인 순서가 나오지 않는다면...?
이미지 촬영 -> 검사 -> AI 데이터 처리 중 다시 이미지 촬영(frame 넘버의 변경) -> 완료 -> 검사 -> AI 데이터 처리 -> 완료
이런 식으로 말이지....그렇다면 AI 데이터 처리중 중간에 frame 넘버가 바뀌게 되고 Ai 데이터는 중간에 비워져 버림.
프로그램은 존재하지 않는 AI 쓰레기 데이터를 처리하며 돌아버리는것.
그런 경우에 대한 예외 처리가 혹시 있는가?
물론 이런 경우는 상상하기 어려운 경우라 당연히 예외처리는 존재하지 않았음.
그러나 지금에 와서 상상이 가능한 건, Thread 들의 역할이었음.
1. 이미지 촬영 Thread
2. 검사 Thread
3. AI 데이터 처리 Thread
1번과 2번은 반드시 1번이 수행되고 2번이 수행되도록 '동기화'가 되어있었음.
그리고 2번과 3번 역시 2번이 수행되고 3번이 수행되는 '동기화'가 이루어 져있었음.
그러나 1번과 3번은 '동기화' 되어 있지 않았음. 즉 3번을 수행하는 동안 1번이 이루어 질 수 있다는 거임.
반대로 1번이 진행되는 동안도 3번이 진행되는 가능성이 있다는 것.
이 역시 미세한 '한 끗' 차였음.
본인은 이곳에 3번이 진행 되는 동안 불행하게도 frame 넘버가 바뀌는 (새 이미지 촬영) 경우가 생긴다면
해당 작업을 더 진행하지 않고. continue (pass) 시키는 코드를 넣었음. 그리고 해당 동작의 유무를 확인하기 위한
로그 역시 추가 했음.
이러한 과정은 순식간에 이루어 졌기에.. 출근 하자마자 바로 짐을 챙기기 시작했음.
나: 로보트 주임님. 의심스러운 파트가 보여 수정했는데, 아무래도 현장에 적용해서 확인해 봐야 할것 같아요.
로보트: 네...? 벌써...요? 이제 10시도 안됐는데....ㅎㅎㅎ
근데 팀장님은 이러실때가 제일 잘 들어맞는거 같더라고요~ 이렇게 또 한건 하시는 걸까...ㅋㅋㅋ
나: ㅎㅎ 괜히 기대했다간 실망만 할꺼에요. 그냥 가볍게 한번 보자구요^^
***
D사 전공정. 3호기로 가서 본인의 코드를 빌드하여 심어놓았음.
나: 지금은 양산중이니까. 이 제품 끝나고 로트(Lot) 변경 할 때, 기존 프로그램 끄시고 제 껄로 해주세요^^
산군 & 로보트 : 기대됩니다...!! 완료처리 할까요 그럼!? ㅋㅋ
나: 자..그럼 당장에 확인은 어려우니 그냥 놔두시죠. ㅎㅎ 기왕 온김에 나머지 '미비사항' 들도 좀 잡아볼까요?
산군: 지금 이 문제만 해결되면...제 재량으로 6~7개 정도의 미비사항은 없던일로 할 수 있습니다!!!
나: ㅋㅋㅋㅋㅋㅋ 오케이 그럼 19개에서 7개 정도는 처리 된걸로 보고 나머지 남은 12개의 '미비사항' 을
없애기 위한 고객의 소망을 한번 들어 볼까요? ㅋㅋ
산군: 아아...우리는 너무 일찍 만난것 같네요 팀장님..
지금처럼만 서로 죽이 맞았다면 그 시절 얼굴 붉힐 일이 없었을텐데...ㅋㅋ
나: 그 시절 우리가 만나지 못했다면 지금의 제가 없었겠죠....ㅎㅎ
산군: 몇년 사이에...팀장님이나 저나 나이가 많이 든거 같은 기분입니다...ㅠ
***
몇일이 지나고... D사의 미비사항 목록이 올라왔고.
그곳엔 3번 광학군의 검사프로그램 원인 불명 뻗음 현상이 깔끔하게 녹색으로 완료처리가 되었음.
그리고 본인에게 보내진 로그파일.
그곳에는 본인의 예상과 일치하는 1번과 3번 Thread의 겹침 동작현상을 표시한
데이터가 들어있었음.
이걸로 2년전의 콩과장과 나를 현재의 내가 이긴거임^^.
고맙다 내 과거와 현재!!!
그외에 모두 녹색으로 빛나고 있는 하위 39개의 항목들...
잇끄 대리와 카푸어 대리의 10개의 메인 이슈들 중에서 가장 난이도 높은 1개는 본인이 해결한게 되었음.
두번째 난이도로는 로보트 주임이 얘기한 Y좌표의 밀림문제. 이건 시간봐서 천천히 나서도 될 것으로..
[한번 고쳐봐라...한 끗차 실력 좀 보자..!!]
잇끄 대리와 카푸어 대리도 성과가 없지 않아 남은 8개 항목 중 4개정도 자체적으로 처리했음.
결국 49개의 고객사 '미비사항' 중 실제로 남은건 4개 정도가 남은거임. Y좌표 밀림 현상을 제외한
나머지는 충분히 대리들의 동력으로 처리 될 만한 것들이라. 이쯤에서 손을 떼도 되는 상황.
그러나 막상 이러한 결과를 받은 대리들은 표정들이 썩 좋지 않았음.
고객사는 완료 처리 목록에 '완료자' 라는 새로운 항목을 만들었고..
그곳에는 빼곡히 본인의 이름으로 가득 채워져 있었음.
아마도...고객은 잇끄 대리와 카푸어 대리에게 무언의 더 분발 하라는 '경고'와 본인에 대한 '공치사'를
생각한 것으로 보였음.
........................
결론적으로 몇년간 쌓여오던 이 '미비사항'이 본인이 투입되고 일주일도 안되어 95% 이상 소거된 거임.
이 결과를 가지고 당당히 월요일 사장님 미팅에 참석할 수 있었음.