도와주세요!!
글 수 15,339
2011.12.27 10:51:05 (*.94.41.89)
22780
안녕하세요 리눅스 디바이스 드라이버 개발업을 하고 있는 사람입니다.
지금 Arm Cortex기반 리눅스에서 루프안에 레지스터를 접근하는 테스트 코드를 만들어 속도를 측정하고 있는데요
user space에서 돌렸을때보다 IOCTL을 통해 kernel space에서 돌렸을때 훨씬 빠른 속도로 코드 수행을 하고 있습니다.
테스트 코드는 다음과 같은데요
for(k = 0; k < 100000; k++) { //I tested this code in user space and kernel space with IOCTL. for(i = 0; i < 1000; i++) { tv2 = *(volatile UInt32 *)(0xfe110080); *(volatile UInt32 *)(0xfe628024) = i + tv2 ; } }
루프 안에는 레지스터를 읽고 쓰는 코드 밖에 없습니다. 이 때 수행 결과를 보면 다음과 같이 1.6배정도 Kernel Layer 속도가 빠른데요.. kernel 모드로 진입하면 해당 프로세스의 스케쥴링 우선순위나 방법등이 달라지게 되는건가요? 아니면 User Layer에서 레지스터 접근시 SVC같은 모드로의 진입을 위해 추가적인 어셈블리 코드가 추가되는건지... 궁금합니다.
User Layer |
Kernel Layer |
52002.16 ms |
32650.53 ms |
2011.12.29 14:40:05 (*.138.143.204)
재미있는 상황이네요.
직관적으로 드는 생각은
첫째로는 유저영역에서의 실행에서 프로세스의 전환으로 인한 시간 손실입니다.
두번째로는 버전에 따라 ioctl 수행시 커널락에 의한 모든 ioctl 에 lock 이 걸리는 것입니다.
자연히 다른 프로세스에서 ioctl 함수의 수행시 block 이 되어 해당 프로세스의 잠김으로
프로세스 점유시간이 높아진다는 것입니다.
세번재로는 대기없는 for, while 문의 경우 커널에서 수행하면 task 의 전환이 막히는 것입니다.
네번째로는 커널 작업의 경우 프로세스의 우선순위가 높아지는 부분입니다.
만약 cpu 내부 레지스터를 커널 공간에서 프로세스의 전환없이 수행한다면
외부 io 없이 I-cache 캐쉬안에서 cpu 내부 bus 만을 이용한 접근으로 굉장히 빠를것 같습니다.
그런데... 유저 공간에서 해당 레지스터 주소로는 어떻게 접근하시는 거죠?