2008년 4월 15일 화요일

입출력방법


입력: 입력장치 buffer에 있는 값을 memory에 써준다.
출력: memory의 값을 출력장치 buffer에 써준다.


입출력방법

  • Polling
    • busy waiting → process가 계속 검사
    • flag가 1이되면 process가 가져다가 memory에 쓴다.
    • 단점: 모든걸 process가 담당하므로 cpu가 아깝다.
  • Interrupt
    • process는 입출력 장치에게 일을 시켜놓고 다른일 한다.
    • 입출력 장치는 시킨 일을 다 하면 process에게 interrupt를 보낸다.
    • process는 하던일을 멈추고 memory의 데이타를 buffer에 혹은 buffer의 데이타를 memory에 옮겨준다.
    • 장점: busy waiting을 하지 않는다. process는 data만 옮겨준다.
    • 단점: interrupt handling을 위한 context switch overhead가 존재한다.
  • DMA(Direct Memory Access)
    • BUS에 DMAC를 달아두고 이것을 이용한다.
    • process가 DMA에게는 입출력 장치와 Memory의 위치를 알려주고, 입출력 장치에게는 DMA로 동작할 것을 알려준다.
    • 시킨 일을 다하면 입출력장치는 DMAC에게 일을 다했다고 한다.
    • DMAC는 process가 시킨일이 끝날 때까지 계속 입출력 장치에게 일을 준다.
    • DMAC는 BUS를 사용하겠다고 request를 보내고 BUS를 획득한 후 process가 지정해준 memory에 data를 쓴다.
    • process가 시킨일을 다하면 DMAC는 process에게 interrupt를 보낸다.

RISC란 무엇인가.


RISC (Reduced Instruction Set Computer)

RISC의 등장배경
  • CISC방식은 명령어도 많고 너무 복잡하여 성능이 저하될 우려가 있었다.
  • 기존 CISC방식보다 좀 더 나은 성능을 보장하기 위하여 RISC가 등장하게 되었다.

RISC의 특징 및 장점
  • 명령어를 줄이고 명령어 format을 동일하게 함으로써 명령어를 간단하게 하여 Decording속도를 높이고 pipelining을 가능하게 하였다.
  • register를 늘림으로써 memory access를 줄여 성능을 높였다.
  • memory access를 할 수 있는 명령어는 LDR과 STR 두 가지로 줄였다. 모든 operation은 register를 사용한다.
  • register set을 여러개 둠으로써 함수 호출을 할 때 memory save를 하지않고 용도별로 register를 사용할 수 있다.
  • Addressing mode(data를 가져오는 방식)이 간단하다.
  • pipelining기법 적용이 쉽다.
  • 하드웨어가 간단하여 발열이 적고 싸다.

RISC의 단점
  • 응용분야가 많아지면서 instruction이 점점 늘어나기 때문에 한계가 있다.

CPU 성능분석


CPU 성능(performance)은 임의의 application의 수행시간에 반비례한다.
cpu excution time은 곧 명령어의 개수를 의미하며, 이는 순수하게 임의의 application이 cpu를 사용한 시간을 뜻한다.


CPU time을 결정하는 세 개의 요소로는 instruction의 개수, CPI, Period가 있으며 다음과 같이 계산한다.
CPU time  = 초/program = instructions/program * clocks/instruction * seconds/clock
      = # of instruction * CPI * Clock rate(Period)

  • instruction의 개수: 프로그램의 크기와는 관계가 없으며 순수하게 수행되는 명령어의 개수이다.
  • CPI: 명령어마다 다르므로 대개는 average로 한다.
  • Clock rate: cycle하나당 걸리는 시간


성능을 좋게 하기 위해서는 CPU time을 줄여야 하는데, 이는 곧 위의 식에서 보는 바와 같이 # of instruction이나 CPI, Clock rate를 줄이면 된다. 이러한 요인들로 하여금 CPU time을 줄이는 방법은 다음과 같다.

  • 동작 clock을 빠르게 한다. (Clock rate를 줄인다)
  • 성능 좋은 컴파일러를 사용하거나 좋은 알고리즘을 이용하여 프로그래밍한다. (# of instruction을 줄인다)
  • pipelining등의 기법을 사용한다.(CPI를 줄인다)

또한, CPU 성능을 높이기 위한 것으로 다음과 같은 기법들을 사용할 수 있다.
  • Pilelining
    • 한국어로 하면 '분업'을 뜻한다.
    • 5단계 pilelining은 Instruction Fetch - Decode - Operand Fetch - Excute - Write Back 의 단계로 이루어진다.
    • 각 단계에 필요한 resource가 따로있다.
    • resource를 효율적으로 사용하기 위한 방법으로 놀고있는 resource를 방지한다.
    • 모두 clock에 동기화 되어 있어서 clock이 튈 때마다 다음 단계로 옮겨진다.
  • Super scalar
    • 명령어 처리하는 모듈이 여러 개 있는 것으로, 모듈이 2개일 경우 2-way super scalar라고 한다.
    • dependency가 없는 여러 개의 명령어를 동시해 수행할 수 있게 한다. (2-way일 경우 2개 동시에 수행 가능)
    • dependency가 없는 명령어 set은 하드웨어가 찾아낸다.
    • 3-way, 4-way, 5-way 등등으로 사용할 수 있다.
    • pilelining과 함께 사용하면 더더욱 성능이 증가된다.
  • VLIM(Very Long Instruction Word)
    • dependency가 없는 명령어를 하나의 명령어로 만들어 parellel하게 실행될 수 있는 것 끼리 묶는다.
    • super scalar와 비슷하게 보이지만 dependency가 없는 명령어 set을 compiler가 찾아내므로 소프트웨어적으로 체크한다는 점이 다르다.


CPU 성능을 측정하는 방법으로 두 가지 기준이 있다. 그 하나가 Response Time이고 나머지 하나가 Throughput이다.
  • Response Time: 프로그램 하나가 시작하면서부터 끝날 때까지의 시간
  • Througput: 단위시간 당 처리하는 일의 양
    예를 들어서, CPU를 두 개로 늘린다면  Response Time에는 변화가 없으나  Througput은 증가할 것이다.

2008년 3월 28일 금요일

리눅스 커널 2.4 - scheduling 과정 중 context switching



/usr/src/linux-2.4.20-8/kernel/sched.c

 

/*

* context_switch switch to the new MM and the new

* threads register state.

*/

static inline task_t * context_switch(runqueue_t *rq, task_t *prev, task_t *next)

/*

* rq(runqueue_t)

* prev(task_t): 현재 실행되고 있는 process

* next(task_t): scheduling받아 이제 실행 될 process

*/

{

           struct mm_struct *mm = next->mm;

           struct mm_struct *oldmm = prev->active_mm;

 

           if(unlikely(!mm)) //이전 process(prev)와 주소공간 공유

           {

                     next->active_mm = oldmm;

 //이전 process(prev) active_mm을 갖는다

                     atomic_inc(&oldmm->mm_count);

//oldmm reference count 증가

                     enter_lazy_tlb(oldmm, next, smp_processor_id()); //TLB설정

           }

           else //다른 주소공간을 가진 process일 경우

                     switch_mm(oldmm, mm, next);

//switch_mm을 호출하여 주소공간switch

          

if(unlikely(!prev->mm)) //현재process(prev) mm포인터가 null이라면

           {

                     prev->active_mm = NULL;

//prev active_mm null로 만들어준다.

                     rq->prev_mm = oldmm;

           }

 

           /* Here we just switch the register state and the stack. */

           switch_to(prev, next, prev); // CPU dependent한 매크로

 

           return prev;

}

 

   이 함수는 schedule() 함수에서 호출된다. scheduler가 다음 수행 될 process를 고르고 나서 호출하는 함수가 바로 이 context_switch함수이다. 현재 수행되고 있는 process의 정보와 다음 수행 될 process의 정보를 argument로 넘겨받는 context_switch함수는 가장먼저 process를 메모리 상에 올리는 일을 수행 한다.  scheduling에 의해 선택되어 다음 번에 실행 될 processmemory management(task_struct안의 mm_struct)  NULL일 경우에는 수행되던 process의 주소공간을 공유하는 것이므로 이전의 process가 가진 mm_struct를 가지게 되고 mm_strcut의 구조체 포인터를 하나 증가시켜준다. NULL이 아닐 경우에는 수행 되던 process와 주소공간이 다른 것이므로 이 process가 가지고 있던 switch_mm이라는 함수를 호출한다. 여기서 switch_mm이 하는 일은 process의 주소 공간을 교체하는 것이다. 만약 수행중인 process(prev) mm NULL이라면 다른 누군가와 주소공간을 공유하고 있다는 뜻이다. 주소공간을 공유하더라도 이제 실행되지 않으면 active_mm NULL값을 주어 실행되지 않는 process임을 나타낸다. 그리고 runqueue prev_mm에 수행되던 process active_mm을 저장해 두었던 oldmm값을 넣는다. 이러한 주소공간 switching이 모두 일어난 후에 switch_to라는 매크로를 호출하여 레지스터의 저장과 저장되어있던 레지스터를 불러오는 일을 한다.

 

/usr/src/linux-2.4.20-8/include/asm-i386/system.h

 

#define switch_to(prev, next, last) do{

           asm volatile(“pushl %%esi\n\t”

“pushl %%edi\n\t”

“pushl %%ebp\n\t”  //레지스터 값 저장

“movl %%esp,%0\n\t”       /* save ESP */

                                “movl %2,%%esp\n\t”    /* restore ESP */

                                “movl $1f,%1\n\t”           /* save EIP */

                                “pushl %3\n\t”                /* restore EIP */

                                “jmp __switch_to\n”          //__switch_to로 점프

                                “1:\t”

                                “popl %%ebp\n\t”

                              “popl %%edi\n\t”

                                “popl %%esi\n\t”  //레지스터 값 로딩

                                :”=m” (prev->thread.esp), “=m” (prev->thread.eip)//출력

                                :”m” (next->thread.exp),”m”(next->thread.eip),                                                “a”(prev), “d” (next)); //입력

}while(0)

 

 이 부분은 CPU dependent한 부분이므로 CPU에 따라 달라질 수 있다. 이 매크로가 하는 일은 현재 실행중인 프로세서의 레지스터들을 저장하고 스케줄링 되어 실행 될 프로세서의 레지스터들을 가지고 오는 것이다. 먼저 실행중인 프로세서의 레지스터들을 stack에 저장하는데 그것이 esi, ebp, esp이다. thread_struct라는 struct 0번째는 esp0가 있는데 이곳에 esp를 저장하고 2번째에 있는 esp값을 esp에 가져다 놓는다. 그리고 1번째에는 eip가 있는데 이 곳에 1f를 저장하여 다음번에 1f라는 곳에서부터 수행할 것을 알려준다. 3번째 값은 fs인데 이곳에 eip를 저장한다. 그리고 나서 __switch_to로 점프뛰는데 이 함수가 실행되고 난 후에는 바뀐 프로세서가 수행될 것이다. context switch가 완전히 다 일어나고 난 후에는 1: 이라고 되있는 leble부터 스케줄링 된 프로세스가 수행된다. 그래서 ebp, edi, esi가 차례대로 복구된다. m은 메모리를 의미하는데 “=”이 출력을, a 또는 d eax, edx레지스터를 뜻한다. 그래서 밑의 3줄 소스를 보면 prev(현재 실행중인 프로세스) eax레지스터에 저장되고 next(스케줄링 받은 프로세스) edx에 저장이 된다.

 

/usr/src/linux-2.4.20-8/arch/i386/kernel/process.c

 

void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)

{

         struct thread_struct *prev = &prev_p->thread,

*next = &next_p->thread;

           int cpu = smp_processor_id();

           struct tss_struct *tss = init_tss + cpu;

           //현재 실행중인 프로세스 prev FPU상태를 저장

 

           /* never put a printk in __switch_to printk() calls wake_up*() indire ctly*/

 

           unlazy_fpu(prev_p);

 

           /* Reload esp0, LDT and the page table pointer: */

           tss->esp0 = next0->esp0;

           //스케줄링 받은 프로세스next esp0(커널 스택 주소)를 저장

 

           /* Load the per-thread Thread-Local Storage descriptor. */

           load_TLS(next, cpu);

 

           /* Save away %fs and %gs. No need to save %es and %ds, as

         those are always kernel segments while inside the kernel. */

           asm volatile(“movl %%fs, %0”: “=m” (*(int *)&prev->fs));

           asm volatile(“movl %%gs, %0”: “=m” (*(int *)&prev->gs));

           //prev 프로세스의 fs gs레지스터 저장

 

           /* Restore %fs and %gs if needed. */

           if(unlikely(prev->fs | prev->gs | next->fs | next->gs)){

                     loadsegment(fs, next->fs);

                     loadsegment(gs, next->gs);

           } //next 프로세스의 fs gs 레지스터 저장

 

           /* Now maybe reload the debug registers */

           if(unlikely(next->debugreg[7])) {

                     loaddebug(next, 0);

                     loaddebug(next, 1);

                     loaddebug(next, 2);

                     loaddebug(next, 3);

                     /* no 4 and 5 */

                     loaddebug(next, 6);

                     loaddebug(next, 7);

           } //디버그 레지스터 로딩

 

           if (unlikely(prev->ioperm || next->ioperm))

           //IOperm시스템 콜일 경우에만 해당.

{

                     if(next->ioperm) {

                                memcpy(tss->io_bitmap, next->io_bitmap,

IO_BITMAP_SIZE*sizeof(unsigned long));

                                tss->bitmap = IO_BITMAP_OFFSET;

                     } else

                                tss->bitmap = INVALID_IO_BITMAP_OFFSET;

           }

}

 

   이 함수가 처음 하는 일은 현재 실행중인 프로세스의 상태를 저장하는 것이다. 그리고 스케줄링 받은 프로세서의 커널 스택 주소를 저장하는데 이 주소는 tss_struct라는 구조체의 esp0필드에 저장되어야 한다. 이 곳에서 CPU가 사용하는 커널 스택 주소가 결정되기 때문이다. 그 후에는 현재 수행중인 프로세스의 fs, gs 레지스터를 저장한다. fs gs는 데이터 이동시 사용자 세그먼트와 커널 세그먼트를 전환하는데 사용한다. 현재 수행중인 프로세스의 레지스터를 저장한 후에 할일은 당연히 다음 수행 될 프로세스의 레지스터를 로딩하는 것이다. 그리하여 fs, gs 레지스터를 로딩시키고 마지막으로 디버그 레지스터들을 로딩시킨다. 만약 프로세스가 IOperm시스템콜을 호출하였다면 그 프로세스가 I/O bitmap을 가지고 있는지 아닌지를 검사한다. 다음 수행될 프로세스가 I/O bitmap을 가지고 있다면 tss unsigned long크기만큼의 byte를 복사하고 그렇지 않다면 port 제어 명령어를 사용할 수 없다는 플래그를 설정한다.

2008년 3월 25일 화요일

천일의 스캔들.


천일의 스캔들.

주연: 스칼렛 요한슨(메리 역), 나탈리 포트만(앤 역), 에릭 바나(헨리8세 역)
감독: 저스틴 채드윅


어느 한 시골에 평화롭게 살아가고 있는 앤, 메리, 조지 삼남매.
아버지는 착실한 한 남자에게서 청혼이 들어오자 욕심많은 첫째 앤보다는 메리가 결혼하기를 원하고, 시골에서 조용히 살고싶은 메리는 그와 결혼하려한다.

그러던 중 삼남매의 삼촌이 되는 사람이 궁정에서 나온다.
그는 삼촌이기도 하지만 궁에서 권력을 쥐고 있는 사람으로 현재의 왕비가 더 이상 왕자를 낳지 못하자 앤을 왕에게 바치려 한다.

메리의 결혼식이 있고 얼마 있지 않아서 삼남매의 집으로 왕이 찾아온다.
앤은 왕의 눈에 들려고 노력하지만 왕이 마음에 들어한건 메리로 결국 메리를 궁으로 데리고 간다.

메리는 자신의 마음을 이해해 주는 왕에게 진심으로 반하게 되고, 왕의 아이를 임신하게 되자, 부모님과 삼촌은 큰 권력을 갖게 된다.
그리고 앤은 궁전 생활을 즐기던 중 정혼자가 있는 다른 귀족과 몰래 결혼하게 되는데, 이 사실을 알게 된 메리와 조지는 앤을 걱정하는 마음에 이 사실을 부모님께 말했지만, 크게 혼나고 프랑스로 쫓겨나게 된 앤은 메리에게 복수할 것을 결심한다.

어느 날, 갑자기 쓰러진 메리는 유산의 위기는 넘겼지만 침대 위에 누워서만 지내야 한다는 진단을 받게 되고, 메리의 삼촌은 이 사실을 알게 되자 초조해하며 앤을 다시 부른다.
프랑스에서 돌아온 앤은 예전과는 다른 모습으로 헨리의 마음을 얻어내지만, 도도한척 동생을 핑계로 왕을 밀어내며 왕을 애태운다.
그리고선, 왕의 마음을 빌미로 메리를 버리게 만들고, 왕비를 폐비 시키게 하고, 카톨릭에서 등을 돌리게 한다. 그렇게 얻어낸 왕의 마음과 왕비의 자리. 그러나 앤은 행복하지가 않다.

스포일러 보기



이 영화를 보기전에 '핸리 8세의 여인들'이라는 책을 봤었다.
두 권짜리 책인데 너무 너무 지루해서 끝까지 보지는 못했지만 책에서 봤던 내용이 약간이나마 나와서 이해하면서 볼 수 있었다.ㅎ
아마, 앤 다음 여왕은 '제인 시무어' 였을 것이다.

생각했던 것 만큼 재밌는 영화는 아니었지만, 지루하지 않게 스토리 전개는 빨랐고,
무엇보다 나탈리포드만과 스칼렛요한슨이 이뻤다+_+)
그리고.. 기대했던 베드신은 없었다.. -_-
(닝기미, 포스터에 낚였다..)

2008년 3월 10일 월요일

NetBeans 시작하기


<< NetBeans 시작하기 >>



1. NetBeans 설치

다운로드하기 

위의 링크에서 다운받을 경우, NetBeans와 JDK가 같이 설치되며 JAVA환경변수에 관한 다른 설정이 필요 없게 된다. ^ㅡ^!!


2.
NetBeans에 대해서

NetBeans란,
- JAVA  Application 개발을 위한 platform
- NetBeans platform을 사용해 개발된 IDE
- Modular Architecture

NetBeans platform이란,
- 재사용 가능한 framework로서 다른 desktop application의 개발을 간단하게 해준다
- user interface management등 여러가지 기능을 제공
- 모듈 집합들로 개발된 application을 실행시킬 수 있는 platform

NetBeans IDE란,
- NetBeans platform기반 위에 구성된 플러그인 집합
- Enterprise, desktop, mobile, web programming 등


3. HelloWorld를 출력하기

NetBeans 실행하기

사용자 삽입 이미지

새 프로젝트를 만든다.

[FILE] → [New Project]
사용자 삽입 이미지
Categories에서 JAVA, Projects에서 Java Application을 선택하고 Next!!

사용자 삽입 이미지
Project Name에 원하는 Project이름을 쓴다.
여기에 쓰는 이름은 새로 생성되는 Project 폴더의 이름이 되는 동시에 곧 만들 application의 package이름이 된다.
제일 아래에 Create Main Class를 선택하면 Main Class를 자동적으로 생성해주는데 hello.Main이라고 하면, hello package의 주 class이름이 Main이 된다. class이름을 바꿔주려면 Main인 부분을 바꿔주면 된다.

코딩하기
package hello;
/**
*
* @author Jessical
*/
public class Main{
/**
* @param args the command line arguments
*/
   public static void main(String[] args){
      System.out.println("Hello World!");
   }
}
실행하기
compile: [build] → [build Main Project]
Run: [Run] → [run main project]
사용자 삽입 이미지
실행하면 output창에 Hello World라고 뜬다-_-)z

바보.


바보.

주연: 차태현(승룡이 역), 하지원(지호 역), 박희순(상수 역)
감독: 김정권


강풀 님의 만화를 영화화한 작품이다. 난 개인적으로 강풀의 만화도 좋아하고 차태현의 연기도 좋아하기 때문에 기대를 조금 했었다. (하지원은 별로 좋아하지 않는데 아주 이쁘게 나왔더라+_+ㅎㅎ) 게다가 동생의 바람잡이까지~!

아저씨 냄새 풀풀나는 동기들과 함께 7명이서 영화관으로 향했다. 그리고 바보를 보는데-_-) 뒤에 초딩이 처음부터 참 거슬리더만,, 마지막까지 기분잡치는데 한몫하더라.

난 아주 재밌게 봤는데, 같이본 남자놈들은 하나같이 재미없었다고 하고, 여자애들은 너무 슬프단다. 난 눈물은 안났지만 그래도 좀 찡하긴 했다.


승룡이는 풍납동 사람들이라면 누구나 다 아는 바보이다. 어렸을 때 연탄가스를 마시고 바보가 되어 버렸다. 아버지는 연탄가스 때문에 돌아가시고, 어머니는 지병으로 돌아가셨지만 동생 지인이가 있어서 행복하다. 친구 상수와 돌아온 지호까지 승룡이는 주변에 너무 좋은 사람들이 많다.

지호는 승룡이의 첫사랑이자 마지막 사랑이다. 피아노를 위해서 출국했지만 큰 무대에 서서는 정작 피아노를 칠 수 없었던 자신을 한탄하며 귀국하고는 다시는 피아노를 치지 않는다. 그러나 승룡이로 인해 차차 닫혔던 마음이 열리고 피아노 앞에 앉게 된다.

상수는 어렸을 때부터 문제아 였지만 순수한 승룡이 앞에서 만큼은 허세를 부리고 싶지도, 강한척 하고 싶지도 않다. 하나밖에 없는 친구 승룡이를 위해서 그리고 승룡이의 행복을 위해서 뭐든지 해주고 싶다.

웃으면서 머리에 피를 흘리던 승룡이는 죽는 순간에 행복했을까. 그토록 듣고 싶었던 지호의 피아노 소리를 들으며 눈을 감는다. 그리고 하늘에서는 눈이 아니 별이 내린다.


영화를 보면 풍납동을 아주 잘 그려냈다. 원작에 충실한 영화라고나 할까. 그래서 더더욱 너무 좋았던 영화였다. 영화적 요소를 가미할 만도 한데 김정권 감독은 그러지 않았다. 하지만 결말을 모두 알고 있음에도, 만화와 같은 내용이라서 뒷내용을 예상할 수 있음에도, 이 영화는 좋았다.

멜로영화를 싫어한다면 비추하지만, 간만에 울어보는 것도 좋지 않을까.ㅎㅎ
게다가 이 영화는 예쁘니까.ㅎ