레이블이 .net인 게시물을 표시합니다. 모든 게시물 표시
레이블이 .net인 게시물을 표시합니다. 모든 게시물 표시

2010년 10월 30일 토요일

.NET TPL 개론

 .NET Framework 4 의 Parallel Task Library는 .NET 에서 기존 코드를 크게 바꾸지 않아도 멀티코어/멀티쓰레드에 맞게 프로그램을 고칠수 있게 해줍니다.  멀티코어 시대가 이미 일반화된 현재로서 멀티 프로세싱/프로그래밍 하여 퍼포먼스를 향상시키는 스킬은 개발자에게 매우 중요한 스킬인데, 이걸 네이티브로 구현하려면 정말 많이 힘이 듭니다. 많은것을 알아야 하고 고민해야되죠... (CPU 명령, CPU 전용 컴파일러, 그리고 스펙...) 그리고 해본분은 알겠지만 디버깅은 정말 죽음입니다. 그래서 닷넷에서는 많은 부분을 추상화 해서 개발자 입장에서 몇가지 자료 구조와 API로 이 문제를 해결할수 있도록 돕고 있습니다.

 

현재 프로그래밍 언어로서는 완벽하게 멀티 프로세싱을 지원하지 않습니다. 일부 언어가 멀티코어 환경에 맞게 문법을 지원해준다고는 하나, 현업에서는 거의 쓰이지 않고 학술적인 목적으로 제한적으로 사용되고 있습니다. 따라서 개발자 니즈로서는 기존 언어가 쉽게 멀티코어로 포팅될수 있기를 바라죠. MS는 이 니즈를 파악하고 니즈에 맞는 라이브러리를 만들었는데 이게 TPL 입니다. 니즈에 대해서 말이 나왔으니, 기존 닷넷에 대해서 약간만 이야기를 하죠... 닷넷이 멀티프로세싱을 처음부터 지원 안한건 아닙니다. 기존 닷넷의 비동기 처리와 쓰레드 풀링 처리는 1.0 때부터 지원하던 것이었습니다. 하지만 간단한 비동기 작업 코드를 짜 보아도 같은 기능의 동기화 코드와는 많은 부분에서 차이가 납니다. 동기를 비동기로 옮기는 것도 어렵고 옮긴다 해도 뻑안나는 같은 동작을 보장하는 것은 정말 어려운 일이었습니다.

 

그래서 MS는 이를 프레임웍 레벨에서 지원해줄수 있는 방법은 없나 고민하게 됩니다. 그럼 MS가 고민하던 때로 돌아가 같이 고민해 볼까요?

 

1) 어차피 모든 부분을 멀티코어로 만들수는 없습니다. 왜냐면 보통 프로그래밍 언어들은 1프로세스 1쓰레드 기준으로 가장 잘 동작하게 만들어져 있죠 (완벽한 멀티코어용 언어로 동작하게 하려면 lock 이나 모니터, 세마포어를 별도로 선언할 필요가 없어야 하지 않을까요? 이러한 동기화 구조들은 현재의 프로그래밍 언어가 멀티코어를 지원하지 않아서 생기는 것입니다.)

2) 그렇다면 멀티코어로 만들면 좋은 부분만을 확실히 멀티코어 동작하게 해주면 됩니다.

3) 어떠한 부분이 멀티코어스러울수 있을까요?


 

멀티코어의 효과가 최대한 있을수 있는 부분들은 대개 상당한 부하가 걸리는 작업들을 수반한 영역들입니다. 그리고 프로그램에서 가장 부하가 많이 걸리는 부분들은 대개 반복작업 - 루프 등에 몰려 있습니다. (중요한 성능개선 포인트인 LRU가 많이 발생하는 곳이기도 합니다.)

(비동기 작업이 꼭 멀티코어스러워야 하는건 아닙니다.  부하가 많이 걸려서 비동기가 필요한 곳은 멀티코어로 바꿀 필요가 있지만, 그렇지 않고 타이밍 때문에 기다려야 하는 상황에서는 멀티코어를 적용하는건 바보같은 짓입니다.)

그리고 이러한 반복작업에서 많이 사용되는 자료구조는 배열-콜렉션과 배열에서 파생된 자료구조들입니다. 이들 자료구조는 멀티프로세싱하게 되면 여러 쓰레드가 동시에 접근하게 되므로, 동기화를 반드시 신경써야 하겠죠.

 

따라서 멀티코어에 대해서 MS는 2가지 전략을 세울수 있습니다.

 


1) 반복작업내 수행되는 작업이 오래 걸리면 이를 멀티쓰레드로 쉽게 옮길수 있도록 해주자

2) 멀티쓰레드에서 사용되는 콜렉션에 대해서는 동기화가 될수 있도록 해주자.

 
그래서 Task Parallel Library가 등장하게 됩니다. 첨부한 PDF에는 이러한 부분에 대해서 대략적인 설명과 함께 실제 적용사례가 나와 있습니다.

1) 의 해결책으로 Task라는 멀티프로세싱을 관리하는 객체에 여러 Task를 만들수 있는 Factory를  두었고, 여기에 람다식으로 태스크를 넣을수 있습니다.
2) 의 해결책으로  System.Collections.Concurrent 네임스페이스 아래의 자료구조들을 예로 들수 있습니다.
 
이 두가지를 조합하여 기존 코드를 멀티코어와 할수 있습니다.
하지만 이것도 어렵다는 개발자의 니즈를 만족시키기 위해서 MS에서는 함수 단위의 비동기화를 아예 언어 단위에서 지원하도록 만들었습니다. : 이것이 최근에 나온 VisualStudio Parallel 으로 보입니다.
 

자세한 이야기는 좀더 나중에...

 

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

2010년 10월 28일 목요일

yield 키워드를 이용한 루프-데이터 반환 최적화

.NET 2.0 부터 있던 키워드이나, 사실상 잘 이용 안되고 있었던 키워드가 있었으니 바로 yield 이다.
yield는 원래 Ruby 에 있던 개념이었는데 제한적으로 C#에서 언어용으로 차용하게 되었다.
하지만 MSIL 수준에서의 지원은 아니고  컴파일시 C# 컴파일러가 자동으로 Code를 생성해준다.
 
 
yield는 return, break 과 같이 사용하며,  yield를 쓰면 루프에서 원하는 조건에 맞는 데이터들의 리스트를 IEnumerable 형태로 얻어올수 있다.
그러니까, 만일 루프를 돌면서 어떤 목록에서 특정 아이템들을 뽑아 따로 리스트를 만들고 싶다면 루프 이전에 컬렉션을 하나 만들고 이 컬렉션에 값을 넣는 코드를 삽입해야 한다.
하지만 yield는 이를 단 한줄로 해결해 준다.

[code csharp]
public class List
{
        //using System.Collections;
        public static IEnumerable Power(int number, int exponent)
        {
                int counter = 0;
                int result = 1;
                while (counter++ < exponent)
                {
                        result = result * number;
                        yield return result;
                 }
        }
        
        static void Main()
        {
                // Display powers of 2 up to the exponent 8:
                foreach (int i in Power(2, 8))
               {
                        Console.Write("{0} ", i);
               }
        }
}
[/code]


 Yield의 구현은 다음 아티클을 참조 : 내부적으로 루프 코드를 State 머신 형태로 변경하여 데이터를 뽑아낸다.
 
Yield는 동일한 기능을 구현하는 코드보다 성능이 더 좋은편이다.
 
 
 
이 글은 스프링노트에서 작성되었습니다.

2010년 9월 10일 금요일

오토마우스 오토키보드 소스

푸 요청으로 올립니다.

옛날에 짠 소스인데... 아래 SendInput  이라는 API 로 마우스/키보드 흉내를 낼수 있습니다.

오토 마우스/ 키보드가 가능하다는 것이지요...

굳이 복잡한 후킹기술 안써도 아래 소스로 충분합니다.

 

 

[code csharp] using System; using System.Runtime.InteropServices; namespace AutoKeyMouseExample { internal class Win32APIs { [DllImport("user32.dll", SetLastError = true)] public static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); [DllImport("user32.dll")] public static extern IntPtr GetMessageExtraInfo(); [StructLayout(LayoutKind.Sequential)] public struct MOUSEINPUT { public int dx; public int dy; public uint mouseData; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] public struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] public struct HARDWAREINPUT { public uint uMsg; public ushort wParamL; public ushort wParamH; } [StructLayout(LayoutKind.Explicit)] public struct INPUT { [FieldOffset(0)] public int type; [FieldOffset(4)] //* public MOUSEINPUT mi; [FieldOffset(4)] //* public KEYBDINPUT ki; [FieldOffset(4)] //* public HARDWAREINPUT hi; } /***************************** * EVENT CONSTANTS * *****************************/ public const int INPUT_MOUSE = 0; public const int INPUT_KEYBOARD = 1; public const int INPUT_HARDWARE = 2; public const uint KEYEVENTF_EXTENDEDKEY = 0x0001; public const uint KEYEVENTF_KEYUP = 0x0002; public const uint KEYEVENTF_UNICODE = 0x0004; public const uint KEYEVENTF_SCANCODE = 0x0008; public const uint XBUTTON1 = 0x0001; public const uint XBUTTON2 = 0x0002; public const uint MOUSEEVENTF_MOVE = 0x0001; public const uint MOUSEEVENTF_LEFTDOWN = 0x0002; public const uint MOUSEEVENTF_LEFTUP = 0x0004; public const uint MOUSEEVENTF_RIGHTDOWN = 0x0008; public const uint MOUSEEVENTF_RIGHTUP = 0x0010; public const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020; public const uint MOUSEEVENTF_MIDDLEUP = 0x0040; public const uint MOUSEEVENTF_XDOWN = 0x0080; public const uint MOUSEEVENTF_XUP = 0x0100; public const uint MOUSEEVENTF_WHEEL = 0x0800; public const uint MOUSEEVENTF_VIRTUALDESK = 0x4000; public const uint MOUSEEVENTF_ABSOLUTE = 0x8000; /***************************** * VIRTUAL KEYS * *****************************/ public enum VK : ushort { /* * Virtual Keys, Standard Set */ VK_LBUTTON = 0x01, VK_RBUTTON = 0x02, VK_CANCEL = 0x03, VK_MBUTTON = 0x04, /* NOT contiguous with L & RBUTTON */ VK_XBUTTON1 = 0x05, /* NOT contiguous with L & RBUTTON */ VK_XBUTTON2 = 0x06, /* NOT contiguous with L & RBUTTON */ /* * 0x07 : unassigned */ VK_BACK = 0x08, VK_TAB = 0x09, /* * 0x0A - 0x0B : reserved */ VK_CLEAR = 0x0C, VK_RETURN = 0x0D, VK_SHIFT = 0x10, VK_CONTROL = 0x11, VK_MENU = 0x12, VK_PAUSE = 0x13, VK_CAPITAL = 0x14, VK_KANA = 0x15, VK_HANGEUL = 0x15, /* old name - should be here for compatibility */ VK_HANGUL = 0x15, VK_JUNJA = 0x17, VK_FINAL = 0x18, VK_HANJA = 0x19, VK_KANJI = 0x19, VK_ESCAPE = 0x1B, VK_CONVERT = 0x1C, VK_NONCONVERT = 0x1D, VK_ACCEPT = 0x1E, VK_MODECHANGE = 0x1F, VK_SPACE = 0x20, VK_PRIOR = 0x21, VK_NEXT = 0x22, VK_END = 0x23, VK_HOME = 0x24, VK_LEFT = 0x25, VK_UP = 0x26, VK_RIGHT = 0x27, VK_DOWN = 0x28, VK_SELECT = 0x29, VK_PRINT = 0x2A, VK_EXECUTE = 0x2B, VK_SNAPSHOT = 0x2C, VK_INSERT = 0x2D, VK_DELETE = 0x2E, VK_HELP = 0x2F, /* * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39) * 0x40 : unassigned * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A) */ VK_LWIN = 0x5B, VK_RWIN = 0x5C, VK_APPS = 0x5D, /* * 0x5E : reserved */ VK_SLEEP = 0x5F, VK_NUMPAD0 = 0x60, VK_NUMPAD1 = 0x61, VK_NUMPAD2 = 0x62, VK_NUMPAD3 = 0x63, VK_NUMPAD4 = 0x64, VK_NUMPAD5 = 0x65, VK_NUMPAD6 = 0x66, VK_NUMPAD7 = 0x67, VK_NUMPAD8 = 0x68, VK_NUMPAD9 = 0x69, VK_MULTIPLY = 0x6A, VK_ADD = 0x6B, VK_SEPARATOR = 0x6C, VK_SUBTRACT = 0x6D, VK_DECIMAL = 0x6E, VK_DIVIDE = 0x6F, VK_F1 = 0x70, VK_F2 = 0x71, VK_F3 = 0x72, VK_F4 = 0x73, VK_F5 = 0x74, VK_F6 = 0x75, VK_F7 = 0x76, VK_F8 = 0x77, VK_F9 = 0x78, VK_F10 = 0x79, VK_F11 = 0x7A, VK_F12 = 0x7B, VK_F13 = 0x7C, VK_F14 = 0x7D, VK_F15 = 0x7E, VK_F16 = 0x7F, VK_F17 = 0x80, VK_F18 = 0x81, VK_F19 = 0x82, VK_F20 = 0x83, VK_F21 = 0x84, VK_F22 = 0x85, VK_F23 = 0x86, VK_F24 = 0x87, /* * 0x88 - 0x8F : unassigned */ VK_NUMLOCK = 0x90, VK_SCROLL = 0x91, /* * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys. * Used only as parameters to GetAsyncKeyState() and GetKeyState(). * No other API or message will distinguish left and right keys in this way. */ VK_LSHIFT = 0xA0, VK_RSHIFT = 0xA1, VK_LCONTROL = 0xA2, VK_RCONTROL = 0xA3, VK_LMENU = 0xA4, VK_RMENU = 0xA5, VK_BROWSER_BACK = 0xA6, VK_BROWSER_FORWARD = 0xA7, VK_BROWSER_REFRESH = 0xA8, VK_BROWSER_STOP = 0xA9, VK_BROWSER_SEARCH = 0xAA, VK_BROWSER_FAVORITES = 0xAB, VK_BROWSER_HOME = 0xAC, VK_VOLUME_MUTE = 0xAD, VK_VOLUME_DOWN = 0xAE, VK_VOLUME_UP = 0xAF, VK_MEDIA_NEXT_TRACK = 0xB0, VK_MEDIA_PREV_TRACK = 0xB1, VK_MEDIA_STOP = 0xB2, VK_MEDIA_PLAY_PAUSE = 0xB3, VK_LAUNCH_MAIL = 0xB4, VK_LAUNCH_MEDIA_SELECT = 0xB5, VK_LAUNCH_APP1 = 0xB6, VK_LAUNCH_APP2 = 0xB7, /* * 0xB8 - 0xB9 : reserved */ VK_OEM_1 = 0xBA, // ';:' for US VK_OEM_PLUS = 0xBB, // '+' any country VK_OEM_COMMA = 0xBC, // ',' any country VK_OEM_MINUS = 0xBD, // '-' any country VK_OEM_PERIOD = 0xBE, // '.' any country VK_OEM_2 = 0xBF, // '/?' for US VK_OEM_3 = 0xC0, // '`~' for US /* * 0xC1 - 0xD7 : reserved */ /* * 0xD8 - 0xDA : unassigned */ VK_OEM_4 = 0xDB, // '[{' for US VK_OEM_5 = 0xDC, // '\|' for US VK_OEM_6 = 0xDD, // ']}' for US VK_OEM_7 = 0xDE, // ''"' for US VK_OEM_8 = 0xDF /* * 0xE0 : reserved */ } } } [/code]

2010년 5월 20일 목요일

Blend & Windows 7 Phone 동영상 한점.

 

Microsoft Blend로 App을 만드는 방법에 대한 90초 짜리 동영상입니다.

간단해보이는군요... 시간나는대로 바로 해서 포스팅 해보겠습니다.

개인적으로 이제부터 화면전환이용이 가능하다는게 좋군요.

 

Get Microsoft Silverlight

2010년 3월 31일 수요일

Windows 7 Phone

 

불곰은 .NET 개발자입니다.

JAVA 개발자가 JAVA로 먹고살듯이

.NET으로 먹고살아 왔고 현재도 그렇습니다.

앞으로도 .NET 으로 먹고살수 있을지는 장담하기 어렵지만

MS가 완전히 망하지 않는 이상, 취미로라도 계속 .NET을 할 것입니다.

 

불곰은 PC Client Application이 전문입니다.

주로 PC나 이에 상응하는 중/고사양 PC에서 돌아가는 어플들을 만들어 왔죠.

하지만 항상 모바일에대한 관심이 있었고 AppStore 가 나왔을때엔

진짜 심각하게 맥을 살까 고민도 했습니다.

비싼돈들여 iPod Touch를 산것도 Apps 때문이었습니다.

 

윈도우 개발자이니까

윈도 모바일 개발을 하면 어떨까 생각도 했습니다만,

역시 윈도 모바일은 하나도 예쁘지 않더군요...

 

"예뻐야 되, 무조건 예뻐야 되" 라는 금자씨의 명언처럼

예쁘지 못한 WM은 저에게 실망 그 자체였고

자연스레 강력한 표현력을 지닌 플래쉬나 WPF등으로 갈아타고 있었습니다.

 

그런데 결국 실버라이트가 일을 냈군요.

 

 

 

 

 

이전부터 실버라이트 모바일이라고 하여 플래쉬 모바일을 맞수로 하여 Feature Phone에서도

미려한 UX를 보여주겠다고 그래서 언제쯤 써볼수 있을까 고대하고 있었습니만...

출시가 늦어 사실상 포기하고 있었습니다.

(쓸수 있었다면... 삼성전자 가전제품의 UX가 실버라이트 모바일이 되었을지도 모릅니다.)

 

그런데 이번 MWC 2010에 발표된 Windows 7 Phone은 실버라이트 모바일이 보여줄수 있는 한계를

훌쩍 뛰어넘어 일반 클라이언트 어플수준의 UX까지 보여주는군요...

"예쁜 디자인"을 신경써온 개발자로서는 멋져보일수 밖에 없습니다. ㅜㅜ

(실버라이트 개발팀 분들 에게: 엉엉 날 가져요 ㅜㅜ 부탁이삼)

 

 제 디자이너 친구 oblidust씨는 이러한 7 phone의 UX적 변화에 대해서

기존의 iPhone 식 고정관념을 깬 새로운 Innovation 이다 라면서 꽤 높은 점수를 주더군요.

 

그에비해, 저와 가까이 있는 삼성의 Bada Phone - Wave는 iPhone 판박이구요...

저희도 Innovation을 한번 했으면 좋겠습니다.

종종 초 일류기업이라면서, 선도하지 않고 따라가는것만 좋아하는것 같아서 안타까워요~

 

삼성 Wave 화면, 실제로 저렇습니다. Wave의 터치위즈 UI가 옴니아 2의 그것보단 빠른것 같아요.

 

일각에서는 과연  MS가 Phone으로 성공할 것인가? 하는 의문을 많이 품고 있습니다만

(사실 MS는 이전에도 몇번 폰을 내놨지만 별로 반응이 좋지 않았답니다.)

제 생각엔, 삼성이 독자 플랫폼 Bada로 iPhone 시장에 도전장을 내밀고 있는것과

마찬가지라 생각합니다. 두고봐야죠.

 

어쨌든 개인적으로는 이러한 WM의 새로운 변화를 저는 새로운 기회로 보고 싶습니다.

그리고 좀더 즐겁게 모바일 개발을 할수 있었음 합니다.

(얼마전에 푸와 WM으로 오랜만에 개발을 했었는데... 힘들어 고생 많이 했습니다. ㅜㅜ)

저도 그러한 즐거운 윈도우 모바일 개발에 뛰어들고자 준비중입니다...

그리고 그러한 발자취를 계속 방문해주신 분들과 공유할 생각입니다...

 

저희 블로그를 지켜봐 주세요~~~!