2007/06/24

1 page proposal

아마도 오래 전에 1 page proposal 이라는 책이 출간되면서 이런 포스팅을 한적이 있다. 알려주는 방식대로 착하게 실행을 하였다. 항목별로 꼼꼼히 채워가려고 노력을 많이 했다. 수학에 정석이 있듯이 기획제안서에도 정석이 있는 것처럼 말이다.
처 음에 시작할때는 위에서 제시한 폼대로 1 page에 무엇을 담아야 할지 많은 고민과 학습이 있었는데 몇번 시도하다 보니까 스스로가 정리가 된다..물론 친절하게 책에서 가르쳐준데로 하면 베스트이겠지만 때론 상황에 따라 맞지 않는 경우도 종종 있다. 그럴때마다 아래와 같이 약간 변형해서 나만의 1 page proposal로 만들어서 제안을 하곤 하는데 내 생각을 정리해서 좋고, 나의 의견을 전달할때 간결해서 좋다라는 생각이 든다.
타이틀 처럼 1 page로 함축시켜서 메세지를 전달해주면 가장 좋은데 그렇지 않을 경우는 2장 짜리도 괜찮은것 같다. 기획서가 시를 쓰는 것도 아니고 너무 함축해서 표현하면 내용이 왜곡되어 전달될 가능성이 있으니까 말이다. 지금은 위의 스타일로 변형해서 팀간(부서간) 커뮤니케이션을 자주 하곤한다.

2007/06/22

고진샤 K600


고진샤의 신제품 미니 노트북 발표회


고진샤 K600 시리즈 블랙 모델


고진샤 K600 시리즈 화이트 모델


또한 이동성과 사용상의 편의성을 고려해 회전 스크린과 터치 스크린 방식이 지원돼 업무용 노트북을 비롯 게임과 동영상, 음악 감상 등의 엔터테이먼트 기능도 보다 편리하게 즐길 수 있다는 장점을 가지고 있다.




회전 방식의 7인치 와이드 LCD가 적용된 K600 시리즈


간편한 터치 스크린 방식


인텔의 저전력 프로세서 A100(ICH7U/인텔 945GU)가 내장돼있으며, 0.99Kg의 초경량급 무게와 최대 7시간의 배터리 등은 미니 노트북으로써의 활용도를 극대화시켜 이동이 잦은 사용자들에게 좋은 선택이 될 것으로 보인다.


0.99kg의 쵸경량급 무게와 최대 7시간의 배터리 사용량


LCD 양 옆으로는 마우스 포인트와 화면 밝기 등 다양한 기능을 컨트롤 할 수 있는 버튼이 위치하고 있어 제한된 공간에서도 요긴하게 사용이 가능하며, LCD 중앙 상단 부분에는 130만 화소의 WEB 캠이 위치하고 있다.



스크린 양 옆으로 위치한 버튼


한 가지 재미있는 특징을 꼽자면 노트북 후면으로 여성 핸드백의 손잡이와 같은 가죽 재질의 손잡이가 달려 있다는 점이다. 이는 이동시 편의성을 감안한 제작사의 배려로 볼 수 있으며, 노트북의 심플한 디자인으로 미루어 보았을 때 특히나 여성 유저들에게 많은 인기를 끌 수 있는 아이디어라 할 수 있을 것이다.




노트북 후면에 장착된 손잡이로 휴대성을 높였다.


이밖에도 윈도우 비스타 운영체제를 사용하는 본 제품은 지상파 DMB와 차량용 네비게이션 프로그램(시터스의 루신 이지윙스)이 탑재돼 있으며, 블루투스를 지원하고 CF 카드 슬롯이 장착돼 있다는 점을 특징으로 꼽을 수 있다.


지상파 DMB와 차량용 네비게이션 프로그램이 탑재


기타 메모리로는 512MB/1GB(DDR2 PC-4200)를 사용하고 있으며, 하드 디스크의 용량은 각각 80GB와 100GB를 사용하고 있고 가격은 80만원 중반대이다. 과연 고진샤의 SA시리즈에 이은 두번째 미니 노트북 K600 시리즈가 국내 소비자들에게 얼마만큼의 반향을 불러일으킬지 그 귀추가 주목된다.

2007/06/14

win FLP와 null.sys

FLP에서는 비주얼 스튜디오 컴파일시 NULL 디바이스 에러가 발생한다.

오늘 하루 그냥 공 쳤다.





Powered by ScribeFire.

Eclipse CDT

꼭 cygwin을 깔아서 써라

mingW는 쓸 생각 하지마라

난 복잡한 설정같은거 질색이다





Powered by ScribeFire.

2007/06/12

volatile

volatile의 경우 어떤 의미에서는 앞에서 설명한 컴파일러의 최적화와 관계있습니다. 그 외에도 CPU 내, 외부의 캐쉬와 갈은 하드웨어적인 최적화와도 관계가 있습니다.

volatile 키워드가 가장 많이 사용되는 경우의 하나가 memory-mapped I/O인 경우입니다. 메모리의 특정 영역을 특정 장치와 연결하여 사용하는 방법입니다. 가장 흔한 예가 비디오 메모리가 되겠고, 그 이외에도 많은 장치들을 이러한 식으로 사용될 수 있습니다.

즉, 자신 엄밀하게 말한다면 컴파일러가 컴파일하고 있는 코드의 상황과는 관계 없이 바뀔 수 있는 메모리 변수가 있다면, 해당 변수에 대해 특별한 최적화를 하지 못하도록 컴파일러를 제약하는 키워드가 volatile입니다.

예를 들어, 0x0C000000 번지에 특별한 장치가 있다고 하겠습니다. 이 장치가 일종의 센서라고 하고 입력되는 센서값의 범위에 따라 다른 동작을 수행하게 프로그래밍을 아래와 같이 하였다고 하면,

int *p = 0x0C000000;

while (1) {

if (*p == 0) {
break;
} else if (*p < lower_limit) {

action 1;
} else if (*p < upper_limit) {

action 2;
}
wait 10 mili-seconds
}


똑똑한 컴파일러는 위의 코드를 아래와 아래와 같이 바꿉니다.


int *p = 0x0C000000;

register int pvar = *p;
if (pvar == 0) {

} else if (pvar < lower_limit) {

while (1) {
action 1;
wait 10 mili-seconds;
}
} else if (pvar < upper_limit) {

while (1) {
action 2;
wait 10 mili-seconds;
}
}


위와 같이 코드가 변형된다면, 프로그래머가 의도한 바와는 다른 결과가 나타나게 됩니다. 이러한 최적화를 억제하는 목적으로 volatile을 사용합니다. 컴파일러는 volatile 키워드가 선언된 변수에 대해서는 무조건 메모리에 접근하여 됩니다. 이러한 memory-mapped I/O 이외에도, 쓰레드 등으로 프로그램을 만들어서 공유변수를 한쪽에서 읽고, 한쪽에서 쓰는 경우도 해당될 수 있으며, 시스템 시간과 같이 특정 위치의 변수값이 자신과는 독립적으로 계속 변하는 경우에도 사용할 수 있습니다.

또는 CPU 내 외부의 캐쉬에 의해서도 이러한 최적화 효과가 나타날 수 있습니다. 캐쉬내에 해당 메모리 번지 값이 저장되어 읽을 때마다 같은 값이 읽히고, 또한 적을 때도 실제 메모리에 저장되지 않고 캐쉬에 임시 보관될 수 있습니다. 다른 경우는 잘 모르겠지만 MIPS의 R 시리즈 CPU에서는 (아마 2000 인가 3000 시리즈로 기억됩니다) 메모리를 두가지 방법으로 접근할 수 있습니다. 메모리 주소의 최상위 비트가 0이면 캐쉬를 거친 일반적인 접근을, 최상위 비트가 1이면 똑같은 주소의 메모리를 캐쉬를 거치지 않고 직접 접근할 수 있습니다. 당연히 이런 컴퓨터의 컴파일러에서 volatile로 선언하면 0C000000이 아니라 8C000000의 메모리를 접근하게 됩니다.



Powered by ScribeFire.

2007/06/08

GCC에선 함수 중첩도 된다

5.4 Nested Functions




A nested function is a function defined inside another function.
(Nested functions are not supported for GNU C++.) The nested function's
name is local to the block where it is defined. For example, here we
define a nested function named square, and call it twice:

     foo (double a, double b)

{

double square (double z) { return z * z; }



return square (a) + square (b);

}


The nested function can access all the variables of the containing
function that are visible at the point of its definition. This is
called lexical scoping. For example, here we show a nested
function which uses an inherited variable named offset:

     bar (int *array, int offset, int size)

{

int access (int *array, int index)

{ return array[index + offset]; }

int i;

/* ... */

for (i = 0; i < size; i++)

/* ... */ access (array, i) /* ... */

}


Nested function definitions are permitted within functions in the places
where variable definitions are allowed; that is, in any block, mixed
with the other declarations and statements in the block.

It is possible to call the nested function from outside the scope of its
name by storing its address or passing the address to another function:

     hack (int *array, int size)

{

void store (int index, int value)

{ array[index] = value; }



intermediate (store, size);

}


Here, the function intermediate receives the address of
store as an argument. If intermediate calls store,
the arguments given to store are used to store into array.
But this technique works only so long as the containing function
(hack, in this example) does not exit.

If you try to call the nested function through its address after the
containing function has exited, all hell will break loose. If you try
to call it after a containing scope level has exited, and if it refers
to some of the variables that are no longer in scope, you may be lucky,
but it's not wise to take the risk. If, however, the nested function
does not refer to anything that has gone out of scope, you should be
safe.

GCC implements taking the address of a nested function using a technique
called trampolines. A paper describing them is available as

http://people.debian.org/~aaronl/Usenix88-lexic.pdf.

A nested function can jump to a label inherited from a containing
function, provided the label was explicitly declared in the containing
function (see Local Labels). Such a jump returns instantly to the
containing function, exiting the nested function which did the
goto and any intermediate functions as well. Here is an example:

     bar (int *array, int offset, int size)

{

__label__ failure;

int access (int *array, int index)

{

if (index > size)

goto failure;

return array[index + offset];

}

int i;

/* ... */

for (i = 0; i < size; i++)

/* ... */ access (array, i) /* ... */

/* ... */

return 0;



/* Control comes here from access

if it detects an error.
*/

failure:

return -1;

}


A nested function always has no linkage. Declaring one with
extern or static is erroneous. If you need to declare the nested function
before its definition, use auto (which is otherwise meaningless
for function declarations).

     bar (int *array, int offset, int size)

{

__label__ failure;

auto int access (int *, int);

/* ... */

int access (int *array, int index)

{

if (index > size)

goto failure;

return array[index + offset];

}

/* ... */

}





Powered by ScribeFire.