반응형

최근에 진행한 프로젝트에서 [언리얼 - 임베디드 SW] UDP 통신 구현한 내용 공유

언리얼 C++ 로 하는 방법도 있지만, 블루프린트로 UDP 통신 구현이 필요할 수 도 있음

 

TCP UDP Socket Client Plugin 구매, 설치

TCP UDP Socket Client Plugin 구매 15,000원 정도

 

사용하는 엔진 버전에 플러그인 설치

 

설치한 플러그인을 해당 프로젝트에 추가

[Blueprint] UDP 초기화

Domain IP, Port, Packet Size 설정, 할당된 ID 저장

[Blueprint] UDP 전송

할당된 ID 에 메시지(String) 전송

[Blueprint] UDP 수신

UDP 수신 이벤트 발생 시, 호출 할 이벤트 정의

윈도우 <-> 유닉스 통신이 안될 경우 해결법

본인 IP 로 데이터 전송하고, 콘솔에서 포트포워딩으로 데이터 넘겨주기

참고: https://www.youtube.com/watch?v=tYo6KCmelM8

 

반응형

'Development' 카테고리의 다른 글

C++ 정리 2  (0) 2021.07.02
Scala - 자료형(객체, 강한 타이핑 시스템)  (0) 2021.07.02
스칼라 - 자바와 비교  (0) 2021.07.02
프롤로그 강점 약점  (0) 2021.07.02
Io 강점 약점  (0) 2021.07.02
반응형

 

RIP, OSPF 비교

 

  RIP (Routing Information Protocol) OSPF (Open Shortest Path First)
최적 경로 계산 알고리즘 벨만-포드 (Bellman-Ford)  다익스트라 (Dijkstra)
라우팅 기준 (매트릭, 거리) 홉 수(Hop Count) 링크의 비용(Cost, 대역폭 기반)

 

 

라우팅 기준

 

 

이동한 횟수.

예를 들어, A->B->D 는 2 이고, A->B 는 1 임.

 

링크의 비용

이동할 때 요구되는 비용의 합.

예를 들어, A->B->D 는 2+2=4 이고, A->B 는 2 임.

 

 

최적 경로 계산 알고리즘

 

벨만-포드

해당 위치까지 누적 매트릭(거리)이 낮은 것을 모든 지점에서 정보를 받아서 갱신함.

위 갱신을 모든 경로들에 대하여 차례대로 확인.

 

경로 확인 순서:

A-B, A-D, B-D, D-C, C-E, C-F, E-F

 

매트릭: 홉

1: A->D->C

2: A->D->C->F

 

매트릭: 링크의 비용

1: A->D->C

2: A->D->C->E->F

 

다익스트라

누적 매트릭(거리)이 낮은 경로 부터 순서 대로 이동함.

만약 해당 경로의 도착지에 먼저 도착한 경로가 있다면, 해당 경로는 제거함.

경로 처리 순서 (괄호 내의 숫자가 처리된 순서)

 

매트릭: 홉

A->B(1)->D(3) [제거]

A->D(2)->C(4)->E(5)

A->D(2)->C(4)->F(6) [종료]

 

매트릭: 링크의 비용

A->D(1)->C(3)->E(5)->F(7) [종료]

A->D(1)->C(3)->F(6) 

A->B(2)->D(4) [제거]

 

 

알고리즘 예시 코드

 

벨만-포드 C++ 코드

예시로 아래 문제에 대한 벨만-포드 기반 최단 경로 찾기 C++ 코드를 작성해봤습니다.

https://www.acmicpc.net/problem/1753

#include <iostream>
#include <vector>
using namespace std;
const int INF = 1000000000;

struct Edge {
    int start, target, cost;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int V, E;
    cin >> V >> E;
    int K;
    cin >> K;

    vector<Edge> edges;
    edges.reserve(E);
    for (int i = 0; i < E; i++) {
        int u, v, w;
        cin >> u >> v >> w;
        edges.push_back({ u, v, w });
    }

    vector<int> dist(V + 1, INF);
    dist[K] = 0;

    // V-1번 반복
    for (int i = 1; i <= V - 1; i++) {

        bool updated = false;

        for (auto& e : edges) {
            if (dist[e.start] != INF && dist[e.start] + e.cost < dist[e.target]) {
                dist[e.target] = dist[e.start] + e.cost;
                updated = true;
            }
        }

        if (!updated) {
            break;
        }
    }

    // (음수 사이클 검사 - 필요하면 사용)
    // for (auto &e : edges) {
    //    if (dist[e.u] != INF && dist[e.u] + e.w < dist[e.v]) {
    //        // 음수 사이클 존재
    //    }
    // }

    for (int i = 1; i <= V; i++) {

        if (dist[i] == INF) {
            cout << "INF";
        }
        else {
            cout << dist[i];
        }

        cout << "\n";
    }

    return 0;
}

 

 

다익스트라 C++ 코드

동일하게 위 문제에 대한 다익스트라 C++ 코드입니다.

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int INF = 1000000000;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int V, E;
    cin >> V >> E;
    int K;
    cin >> K;

    vector<vector<pair<int, int>>> graph(V + 1);
    for (int i = 0; i < E; i++) {
        int start, target, cost;
        cin >> start >> target >> cost;
        graph[start].push_back({ target, cost });
    }

    vector<int> dist(V + 1, INF);
    dist[K] = 0;

    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    pq.push({ 0, K });

    while (!pq.empty()) {
        
        auto [cost, u] = pq.top();
        pq.pop();

        if (cost > dist[u]) {
            continue;
        }

        for (auto& edge : graph[u]) {
            
            int v = edge.first;
            int w = edge.second;
            
            if (dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                pq.push({ dist[v], v });
            }
        }
    }

    for (int i = 1; i <= V; i++) {
        
        if (dist[i] == INF) {
            cout << "INF";
        }
        else {
            cout << dist[i];
        }

        cout << '\n';
    }

    return 0;
}
반응형
반응형

범용 게이트

: 어떤 논리 회로든 단독으로 구현할 수 있는 논리 게이트

  대표적으로 NAND 게이트NOR 게이트가 있음

 

회로도

 

게이트별 트렌지스터 개수

( 표준 CMOS 기준, 2입력 게이트)

: 범용 게이트 NAND, NOR 가 AND, OR 보다 트렌지스터 수가 적다.

  따라서  

게이트 트랜지스터 수
NOT (인버터) 2 (1 PMOS + 1 NMOS)
NAND2 4 (2 PMOS, 2 NMOS 직렬)
NOR2 4 (2 PMOS 직렬, 2 NMOS)
AND2 6 (NAND2 + 인버터 → 4 + 2)
OR2 6 (NOR2 + 인버터 → 4 + 2)

 

과거 마이크로 프로세서

: 초기 IC(집적회로)는 트랜지스터 수가 수십~수백 개 수준이므로 가능한 한 단순해야 했음 

  여러 가지 게이트를 따로 제작하면 공정이 복잡해지고 원가↑, 수율↓

  따라서 한 종류의 게이트 (범용 게이트) 만 사용한 경우 많았

 

 

현대 마이크로 프로세서

: 과거보다 효율성을 더 추구하여 아래와 같은 필요에 따라 다양한 게이트 사용함

 

  • 트랜지스터 수 최소화
    • NAND/NOR만 쓰면 불필요하게 게이트 수가 늘어날 수 있음.
    • 예: 단순 NOT을 NAND로 만들면 트랜지스터 4개 필요 → 그냥 인버터 쓰면 2개로 구현 가능
  • 속도 최적화
    • CMOS에서 게이트 지연(delay)은 트랜지스터 직렬·병렬 수에 크게 좌우됨.
    • 따라서 특정 논리를 NAND만으로 표현하면 불필요하게 깊은 게이트 체인이 생김 → 지연 ↑
  • 소비전력과 면적 최적화
    • 전력은 게이트 수와 배선 길이에 비례.
    • 설계자는 라이브러리에서 가장 효율적인 “표준 셀(standard cell)”을 골라 씀.
    • 표준 셀 라이브러리는 NAND, NOR, INV, XOR, MUX 등 다양한 기본 게이트를 포함.
  • 특수 연산
    • CPU ALU에는 XOR, MUX, AOI (AND-OR-Invert), OAI (OR-AND-Invert) 같은 복합 게이트가 자주 쓰임.
    • 이런 게이트는 단순 NAND 조합보다 속도·면적 최적화가 잘 됨.

 

반응형
반응형

아래의 문제에 대하여 C++ 의 해쉬에 해당하는 unordered map 과 array 로 구현했을 때, 속도 비교를 하고자 합니다

최빈값 문제는 다음과 같습니다

Array 기반으로 해결하는 방법의 코드입니다

#include <string>
#include <vector>

using namespace std;

int solution(vector<int> array) {
    int array_list[1000] = {0,};
    int max = 0;
    int out = -1;
    for (int i = 0; i < array.size(); i++) {
        array_list[array[i]] += 1;
        if (array_list[array[i]] > max) {
            max = array_list[array[i]];
            out = array[i];
        } else if (array_list[array[i]] == max) {
            out = -1;
        }
    }
    return out;
}

 

Hash 기반으로 해결하는 다른 분의 코드입니다.

#include <string>
#include <vector>
#include <unordered_map>
using namespace std;

int solution(vector<int> array) {
    int answer = 0;
    int maxV = 0;

    unordered_map<int,int> um;
    for(const auto v : array)
    {
        um[v]++;
    }

    for(const auto& v : um)
    {
        if(v.second > maxV)
        {
            maxV = v.second;
            answer = v.first;
        }
        else if(v.second == maxV)
        {
            answer = -1;
        }
    }

    return answer;
}

 

실행결과: 특정 데이터에서 Hash 기반 구현이 Array 기반 구현보다 느린 것을 확인할 수 있습니다

반응형
반응형
#include <string>
#include <vector>

using namespace std;

vector<vector<int>> solution(int n) {
    vector<vector<int>> answer;
    for (int i = 0; i < n; i++) {
        answer.push_back(vector<int>{});
        for (int j = 0; j < n; j++) {
            answer[i].push_back(0);
        }
    }
    int cur = 1;
    int row = 0;
    int col = 0;
    int dir = 0; // 0(right) > 1(down) > 2(left) > 3(up)
    int seq_num = true; // 1 > 0 > 1 > 0 > 1 > ...
    int cur_end = n;
    int cur_seq_len = n;
    while (cur <= n*n) {
        answer[row][col] = cur;
        if (cur == cur_end) {
            dir = (dir + 1) % 4;
            if (seq_num == true) {
                cur_seq_len -= 1;
            }            
            cur_end += cur_seq_len;
            seq_num = seq_num == false;
        }
        cur += 1;
        if (dir == 0) {
            col += 1;
        } else if (dir == 1) {
            row += 1;
        } else if (dir == 2) {
            col -= 1;
        } else if (dir == 3) {
            row -= 1;
        }
    }
    return answer;
}

 

Tip: 상태 정보의 변화를 통해 디버깅

 

반응형
반응형

 

 

2740번: 행렬 곱셈

첫째 줄에 행렬 A의 크기 N 과 M이 주어진다. 둘째 줄부터 N개의 줄에 행렬 A의 원소 M개가 순서대로 주어진다. 그 다음 줄에는 행렬 B의 크기 M과 K가 주어진다. 이어서 M개의 줄에 행렬 B의 원소 K개

www.acmicpc.net

 

#include <iostream>
#include <vector>
using namespace std;

void makeVector(vector<int>& Mat, int row, int col);

int main() {

	int N, M, K;
	vector<int> A, B, AB;

	cin >> N >> M;
	A.reserve(sizeof(int) * N * M);
	makeVector(A, N, M);
	
	cin >> M >> K;
	B.reserve(sizeof(int) * M * K);
	makeVector(B, M, K);

	AB.reserve(sizeof(int) * N * K);

	for (int i = 0; i < N; i++) {
		for (int j = 0; j < K; j++) {
			int ele = 0;
			for (int k = 0; k < M; k++) {
				ele += A[i * M + k] * B[j + k * K];
			}
			cout << ele << ' ';
		}
		cout << endl;
	}

	return 0;
}

void makeVector(vector<int>& Mat, int row, int col) {
	int tmp;
	for (int i = 0; i < row; i++) {
		for (int j = 0; j < col; j++) {
			cin >> tmp;
			Mat.push_back(tmp);
		}
	}
}
입력 :
3 2
1 2
3 4
5 6
2 3
-1 -2 0
0 0 3

출력 :
-1 -2 6
-3 -6 12
-5 -10 18
반응형

+ Recent posts