글

라벨이 C language인 게시물 표시

SMID 병렬프로그래밍

이미지
SIMD(Single Instruction Multiple Data) SIMD란 병렬 컴퓨팅의 한 종류로, 하나의 명령어로 여러 개의 값을 동시에 계산하는 방식이다. 변수형 typedef union __declspec (intrin_type) __declspec (align( 16 )) __m128i { __int8 m128i_i8[ 16 ]; __int16 m128i_i16[ 8 ]; __int32 m128i_i32[ 4 ]; __int64 m128i_i64[ 2 ]; unsigned __int8 m128i_u8[ 16 ]; unsigned __int16 m128i_u16[ 8 ]; unsigned __int32 m128i_u32[ 4 ]; unsigned __int64 m128i_u64[ 2 ]; } __m128i ; 사용법 __declspec(align __declspec (align( 32 )) struct s1 { int a, b, c, d; // sizeof(struct s1)는 32. 16바이트가 덧붙여진다. }; __declspec (align( 8 )) struct s2 { int a, b, c, d; // sizeof(struct s2)는 16. }; __mm_loadu_si128 __m128i a; // 128bit aligned 자료형 __declspec (align( 16 )) short v1[ 6 ] = { 1 , 2 , 3 , 4 , 5 , 6 }; //short 단위로 채움 a = _mm_loadu_si128(( __m128i *)v1);   _mm_set1_epi32 __m128i b; // 128bit aligned 자료형 b = _mm_set1_epi32(( int ) 5 ); //in...

2020 카카오 코딩테스트 - 괄호 변환

이미지
문제 설명 https://programmers.co.kr/learn/courses/30/lessons/60058 간단히 설명하자면 괄호 '('와 ')'를 올바르게 배치하는 문제입니다. 풀이 핵심 keyword 재귀함수, 스택(stack) 문제풀이 문제 설명에 답이 대부분 있습니다. 첫번째 단계 는 주어진 p를 u,v로 나누는것 입니다. u는 더이상 나눠지지 않는 괄호의 첫 문자열, v는 나머지 입니다. 예를들어 "(())()()"와 같은 문자열이 주어졌다면 u는 "(())" v는 "()()"가 됩니다. 처음 문자열로 "(" 또는 ")"가 올수있기때문에 아무거나 기준점을 잡고 아래와 같이 계산했습니다. "("를 기준으로 "("가 나오면 +1, ")"가 나오면 -1로 계산하여 첫 0이 되는 시점이 더이상 나눌 수 없는 괄호로 판단 + 수치가 되었다가 0이 되는 순간 (로 시작해서 )로 끝나는 경우입니다. i.e. "(())()()" - 수치가 되었다가 0이 되는 순간 )로 시작해서 (로 끝나는 경우입니다. i.e.  "))))((((()()" static void _divide_uv (string p, string &u, string &v) { //divide u,v int left = 0 ; int copylen = 0 ; for ( int i= 0 ;i<p.size();i++) { if (p[i] == '(' ) { left++; } else { left--; } if (left== 0 ) { copylen = i+ 1 ; cout << "count " << copylen << endl; break ...

HackerRank algorithm - Jumping on the Clouds (C)

이미지
HackerRank Algorithm 문제풀기 Issue : Jumping on the Clouds 문제 설명 https://www.hackerrank.com/challenges/jumping-on-the-clouds 문제를 간략히 설명하면 구름을 점프하며 뛰어넘는 게임입니다. 구름은 0,1 두가지 타입이 있습니다. 0의 구름은 점프가 가능하고 1은 불가능합니다. 각 구름간의 거리는 1이며 최대 최대 점프가 가능한 거리는 2입니다. 해결방법 최대 2칸을 갈 수 있는 경우의수를 집중해서 풀어봤습니다. 현재 위치가 0일때에 올 수 있는 경우의 수는 3가지 입니다. 1. 시작점 2. 1칸을 움직인 상태 3. 2칸을 움직인 상태 : 이 경우의 수는 최종 2칸 움직였으며 턴이 종료됩니다. 현재 위치가 1일때에 올 수 있는 경우의 수는 2가지 입니다. 1. 1칸 움직인 상태 2. 2칸 움직인 상태 : 이 경우의 수는 한걸음 뒤로 가서 최종 1칸 움직인 형태로 턴이 종료됩니다. 현재 위치가 0이며 한번도 움직인적이 없는 경우 한 칸 움직여야하며, 다음에 올 수 있는 경우의 수는 0또는 1입니다. 현재 위치가 0이며 직전 1칸 움직였던 경우 한 칸 움직여야하며, 다음에 올 수 있는 경우의 수는 0또는 1입니다. 다음 턴에 2칸 움직이며 0인경우 2칸을 움직인 상태로 최종 턴이 종료되며 1인 경우 2칸을 움직인 뒤 1칸을 돌아와 1칸을 움직인 상태로 최종 턴이 종료됩니다. 현재 위치가 1이며 직전 1칸 움직였던 경우 한 칸 움직여야하며, 다음에 올 수 있는 경우의 수는 0입니다. 다음 턴에 2칸 움직이며 최종 턴이 종료됩니다. 종합 :  코드   // Complete the jumpingOnClouds function below. int  jumpingOnClouds( int  c_count,  int * c) {     ...

HackerRank algorithm - Sales By Match (C)

이미지
HackerRank Algorithm 문제풀기 Issue : Sales By Match 문제 설명 https://www.hackerrank.com/challenges/sock-merchant/problem 문제를 간단히 설명하자면 배열이 주어지고, 배열에서 짝이 맞는 갯수를 찾는 문제입니다. 해결방법 우선 비교를 위해 아래와 같이 중복된 배열을 제외한 모든 배열을 선회하여 비교합니다. 하지만 서로 짝을 찾은 경우에는 해당 인자는 더이상 비교할 필요가 없으므로 건너뜁니다. 코드   // Complete the sockMerchant function below. int  sockMerchant( int  n,  int  ar_count,  int * ar) {      int  sum= 0 ;      for ( int  i= 0 ;i<ar_count;i++) {          if (*(ar+i) == - 1 )  continue ;          for ( int  j=i+ 1 ;j<ar_count;j++) {              if (*(ar+j) == - 1 )  continue ;              if (*(ar+i) == *(ar+j)) {  ...

Message queue callback in c language

이미지
Message queue callback? message queue callback이란 message를 보내서 queue에 저장하면 callback으로 저장된 message가 전달되는 구조입니다. 언제 사용되는가? 일반적으로 lib의 callback을 user쪽에 구현하는 경우, 해당 callback에서 함수를 만들어 처리하는 경우가 많습니다. 하지만 lib의 callback은 실제로 lib내부에 존재하는 형태라는 것을 알아야 합니다. 따라서 lib callback에서 시간을 많이 소비하는 경우에는 사용하는 lib가 오동작 할 수 있습니다. 이렇기 때문에 lib에서 제공한 callback을 user쪽에서 사용하는 경우에는 전달된 data를 queue에 담아놓고 다른 thread에서 처리하는 것이 좋습니다. 이것을 지원하기 위해 message queue callback을 사용했습니다. 구조 분석 샘플 소스 분석 git clone https://github.com/juwith/jsutils.git git checkout 707a7e09a96ac611fb1c2a193bf0ee21ea3065fd cd message_queue 하나의 쓰레드가 돌면서 queue에 data가 있으면 user callback에 알려줍니다. message를 보내면, queue에 저장을 합니다. 즉, message를 보내면 일정 시간마다 user에게 다시 메세지를 전달해줍니다. message send void _message_send (Message * msg, void * item) { pthread_mutex_lock( & msg -> msgMtx); Queue * q = msg -> queue; Queue_Enqueue(q,item); pthread_mutex_unlock( & msg -> msgMtx); } message 쓰레드 void * ...

Callback in c language

이미지
Callback 이란? callback이란 말 그대로 call을 했을 때 무언가 응답(back)이 오는 것 입니다. 언제 사용되는가? callback은 여러 상황에서 사용하겠지만, 제가 경험한 바로는 가장 많이 사용되는 곳은 계층을 나눌 때 입니다. 계층을 나누게 되면 각각의 계층 간 독립적인 동작을 합니다. 단순 함수 call을 하고 return type으로 결과를 받아볼 수도 있습니다. 하지만 함수가 return이 되고 다른 thread에서 내부 동작이 일어난다고 생각해봅시다. 진행되는 중 에러가 발생할수도 있고, 처리가 완전히 끝나는 시점을 알아야 할 필요도 있습니다. 물론 동작이 모두 끝난 후 함수를 return할 수도 있겠습니다. 이럴 경우 한 번 함수를 call하는데 시간이 오래걸리기 때문에 사용자 입장에서 고려해야할 점이 많습니다. 샘플 소스 분석 git clone https://github.com/juwith/jsutils.git git checkout b3fa4c4f2642efbcc2dbeefaa1fdee41b88f2f41 cd callback Library typedef struct { void ( * JuCB_action_cb)( void * pvPrivate, JuCB_ACT_TYPE event); void ( * JuCB_state_cb)( void * pvPrivate, JuCB_STA_TYPE event, char * msg); } JuCB_CallBack_T; 여러 callback을 등록할 수 있도록 구조체형으로 타입 정의 void _jucb_register_cb (JuCB * obj, JuCB_CallBack_T * cb) { obj -> cb.JuCB_action_cb = cb -> JuCB_action_cb; obj -> cb.JuCB_state_cb = cb -> JuCB_sta...

Data structure - queue(FIFO) in c language

이미지
Queue란? Queue란 자료구조 중 하나로 처음 입력된 데이터가 처음 빠져나가는(First In First Out, FIFO) 형태의 자료구조입니다. 위와 같이 A블럭의 데이터가 처리된 후 B블럭의 데이터가 처리되어야 하는 시스템이라고 가정해봅시다. 두 블럭이 동일 자원을 사용하기때문에 A블럭은 B블럭의 데이터 처리가 완료될 때 까지 팬딩상태입니다. 이 때 queue형태의 버퍼가 있다면 A,B 블럭 모두 독립적으로 수행될 수 있습니다. 구조 queue는 data와 다음 queue(node)를 가지고 있습니다. 그리고 시작 위치의 queue(front)와 마지막 위치의 queue(rear)를 가르키는 포인터가 있습니다. 이 구조에서 데이터를 추가할 때(enqueue)는 큐의 메모리를 하나 생성한 후, 원래의 rear의 다음 포인터를 생성한 큐에 지정합니다. 그리고 rear를 새로 생성한 큐로 지정을 하게 되면 위의 그림처럼 데이터가 하나 연결됩니다.   데이터를 빼낼때(dequeue)는 우선 front의 queue메모리를 해제한 후 front를 다음 큐에 연결합니다. 그리고 가지고있던 data를 반환하면 됩니다. 샘플 소스 분석 위의 구조대로 소스가 짜여진 샘플 코드입니다. git clone https://github.com/juwith/jsutils.git git checkout 6d1bffa03ceae289c2c67a38e1d60b229b2b7ef7 cd queue 기본 queue의 데이터형입니다. typedef struct qData qData; struct qData { qData * next; void * item; }; typedef struct Queue { qData * front; qData * rear; int nItem; struct QueueFuncTab...

Object Oriented Programming(OOP) in c - example

이미지
OOP OOP란 객체 지향으로 프로그래밍을 하는것을 말합니다. 일반적으로 C는 절차지향언어로 알고있는데, C도 구조를 잘 잡으면 객체지향으로 프로그래밍을 할 수 있습니다. 예제. git clone https://github.com/juwith/oop-animal.git git checkout aa07ba3a4e6956ca18065e4b434791b5ae622e45 구조 annimal이라는 객체를 생성합니다. 가장 base object입니다. 그리고 annimal 밑에는 amphibia, mammal등과 같이 annimal을 나눌 수 있는 객체들이 있습니다. 이 객체(amphibia, amammal...) 밑에는 실제 동물의 객체들이 있습니다. animal의 객체는 모든 하위 객체가 할 수 있는 동작(method), 데이터(private)를 정의할 수 있습니다. amphibia,mammal... 객체에는 animal을 상속받아 추가로 필요한 동작이나 데이터를 정의할 수 있습니다. (...을 붙인 이유는 확장이 가능하기 때문입니다.) cat,dog는 mammal 객체를 상속받았는데, mammal은 animal을 상속받았기 때문에 아래와 같은 동작이 가능합니다. animal의 method,data를 사용 가능함. mammal의 method,data를 사용 가능함 prog는 amphibia를 상속받았기 때문에 mammal의 method와 data는 사용하지 못하며 아래와 같은 동작이 가능합니다. animal의 method,data를 사용 가능함. amphbia의 method,data를 사용 가능함 소스트리 샘플 소스의 트리를 보는 방법은 아래와 같습니다. src : 객체 lib  - base : base object  - amphbia, mammal : base object를 상속받은 object tests : 객체 lib...

C language - Memory of C programming

이미지
C언어에서는 아래 5가지 블럭의 메모리를 사용합니다. Stack Heap Uninitialized Data(.bss) Initialized Data(.data) Code segment(.text) Stack stack 메모리는 일시적인 메모리로 사용이 됩니다. 이름에서 볼 수 있는 것과 같이 stack 구조로 메모리에 마지막에 넣어진 데이터가 처음으로 빠지는 형태(LIFO) 입니다. 함수가 호출될 때 마다 메모리가 할당되며 함수 호출이 끝나면 메모리 할당이 해제됩니다. 자동으로 할당/해제 되는 메모리이기 때문에 사용자가 메모리에 해제를 신경 쓸 필요가 없습니다. e.g. Heap heap 메모리는 프로그램이 실행되는 동안 할당됩니다. 따라서 사용 후 메모리 해제를 하지 않으면 메모리 누수가 발생할 수 있습니다. e.g. Uninitialized Data 이 메모리 영역에는 초기화 되지 않은 전역변수, static 변수가 할당됩니다. Initialized Data 이 메모리 영역에는 초기화 된 전역변수, static 변수가 할당됩니다. Code segment 이 메모리에는 실행 가능한 프로그램 코드를 저장하거나 const(읽기 전용)메모리 입니다. e.g.

C language - scope rules

이미지
scope란? 말 그대로 볼 수 있는 범위를 뜻합니다. scope를 이해하기 위한 예제 소스 결과 -bash-4.2$ ./hello i in condition : 0 i in condition : 1 i in condition : 2 i in condition : 3 i in condition : 4 i in condition : 5 i in condition : 6 i in condition : 7 i in condition : 8 i in condition : 9 i in func 5 i in main 0 일반적으로 프로그래밍을 할 때 숫자를 세는 변수는 x,y또는 i,j와 같은 변수를 많이 사용합니다. 또한 시작에 변수를 모두 정의해놓고 함수 내부에서 사용하는 경우가 많습니다. 이럴 경우 함수 line이 길어지면 변수를 보기 위해 다시 함수 처음 위치까지 올라가서 소스를 참고해야합니다. 따라서 scope는 최대한 작을 수록 좋습니다.