f
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,3 @@
|
|||||||
build
|
build
|
||||||
output.txt
|
output.txt
|
||||||
data
|
data
|
||||||
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"algorithm": "cpp"
|
"algorithm": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(MyCUDAProject LANGUAGES CXX CUDA)
|
project(MyCUDAProject LANGUAGES CXX CUDA)
|
||||||
|
|
||||||
# add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/source-charset:utf-8 /execution-charset:utf-8>")
|
# add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/source-charset:utf-8 /execution-charset:utf-8>")
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
src/main.cu
|
src/main.cu
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(my_cuda_app ${SOURCES})
|
add_executable(my_cuda_app ${SOURCES})
|
||||||
|
|
||||||
set_target_properties(my_cuda_app PROPERTIES
|
set_target_properties(my_cuda_app PROPERTIES
|
||||||
CUDA_ARCHITECTURES 89
|
CUDA_ARCHITECTURES 89
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
input_path = "../data/structures_end_ac.txt"
|
input_path = "../data/structures_end_ac.txt"
|
||||||
cities_output_path = "../data/cities.txt"
|
cities_output_path = "../data/cities.txt"
|
||||||
stronghold_output_path = "../data/strongholds.txt"
|
stronghold_output_path = "../data/strongholds.txt"
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
import os
|
import os
|
||||||
|
|
||||||
def extract_structure_data(input_path):
|
def extract_structure_data(input_path):
|
||||||
cities = []
|
cities = []
|
||||||
strongholds = []
|
strongholds = []
|
||||||
with open(input_path, 'r') as file:
|
with open(input_path, 'r') as file:
|
||||||
reader = csv.reader(file, delimiter=';')
|
reader = csv.reader(file, delimiter=';')
|
||||||
for row in reader:
|
for row in reader:
|
||||||
if len(row) > 1 and (row[1] == 'ancient_city'):
|
if len(row) > 1 and (row[1] == 'ancient_city'):
|
||||||
cities.append((row[2], row[3]))
|
cities.append((row[2], row[3]))
|
||||||
if len(row) > 1 and (row[1] == 'stronghold'):
|
if len(row) > 1 and (row[1] == 'stronghold'):
|
||||||
strongholds.append((row[2], row[3]))
|
strongholds.append((row[2], row[3]))
|
||||||
|
|
||||||
return cities, strongholds
|
return cities, strongholds
|
||||||
|
|
||||||
def write_to_file(data, output_path):
|
def write_to_file(data, output_path):
|
||||||
with open(output_path, 'w') as file:
|
with open(output_path, 'w') as file:
|
||||||
for item in data:
|
for item in data:
|
||||||
file.write(f"{item[0]} 100 {item[1]}\n")
|
file.write(f"{item[0]} 100 {item[1]}\n")
|
||||||
|
|
||||||
cities, strongholds = extract_structure_data(input_path)
|
cities, strongholds = extract_structure_data(input_path)
|
||||||
write_to_file(cities, cities_output_path)
|
write_to_file(cities, cities_output_path)
|
||||||
write_to_file(strongholds, stronghold_output_path)
|
write_to_file(strongholds, stronghold_output_path)
|
||||||
140
report.md
140
report.md
@@ -1,70 +1,70 @@
|
|||||||
# 고대 도시 + 엔드 근접점 탐색
|
# 고대 도시 + 엔드 근접점 탐색
|
||||||
|
|
||||||
## 데이터
|
## 데이터
|
||||||
|
|
||||||
- 수집 범위: `AABB (-50000 -50000) (50000 50000)`
|
- 수집 범위: `AABB (-50000 -50000) (50000 50000)`
|
||||||
- 수집 대상: `minecraft:stronghold`, `minecraft:ancient_city`
|
- 수집 대상: `minecraft:stronghold`, `minecraft:ancient_city`
|
||||||
|
|
||||||
## 실험 환경
|
## 실험 환경
|
||||||
|
|
||||||
- CUDA 12.8 GPU 가속
|
- CUDA 12.8 GPU 가속
|
||||||
- 3차원 좌표 데이터 2쌍 -> Grid Search에 적합
|
- 3차원 좌표 데이터 2쌍 -> Grid Search에 적합
|
||||||
- y좌표 무시 필요성 있음
|
- y좌표 무시 필요성 있음
|
||||||
|
|
||||||
## 실험 결과
|
## 실험 결과
|
||||||
|
|
||||||
- 실험 시간: 183.18ms
|
- 실험 시간: 183.18ms
|
||||||
|`minecraft:ancient_city (x, z)`|`minecraft:stronghold (x, z)`|`distance (blocks)`|
|
|`minecraft:ancient_city (x, z)`|`minecraft:stronghold (x, z)`|`distance (blocks)`|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
|2880, 7040|2900, 6996|48.3322|
|
|2880, 7040|2900, 6996|48.3322|
|
||||||
|-736, 1600|-812, 1492|132.061|
|
|-736, 1600|-812, 1492|132.061|
|
||||||
|-320, -13648|-364, -13804|162.086|
|
|-320, -13648|-364, -13804|162.086|
|
||||||
|-20160, 80|-19980, 52|182.165|
|
|-20160, 80|-19980, 52|182.165|
|
||||||
|-20176, -3424|-20380, -3468|208.691|
|
|-20176, -3424|-20380, -3468|208.691|
|
||||||
|-19408, -6768|-19420, -6988|220.327|
|
|-19408, -6768|-19420, -6988|220.327|
|
||||||
|10464, 17488|10244, 17652|274.401|
|
|10464, 17488|10244, 17652|274.401|
|
||||||
|-15632, -12848|-15388, -12716|277.417|
|
|-15632, -12848|-15388, -12716|277.417|
|
||||||
|-19760, -160|-19980, 52|305.522|
|
|-19760, -160|-19980, 52|305.522|
|
||||||
|10560, 17712|10244, 17652|321.646|
|
|10560, 17712|10244, 17652|321.646|
|
||||||
|20064, -3376|20068, -3724|348.023|
|
|20064, -3376|20068, -3724|348.023|
|
||||||
|-20288, -144|-19980, 52|365.075|
|
|-20288, -144|-19980, 52|365.075|
|
||||||
|-6752, 5616|-6412, 5764|370.815|
|
|-6752, 5616|-6412, 5764|370.815|
|
||||||
|-14112, -688|-13772, -844|374.08|
|
|-14112, -688|-13772, -844|374.08|
|
||||||
|-14592, 3280|-14300, 3524|380.526|
|
|-14592, 3280|-14300, 3524|380.526|
|
||||||
|8832, 6704|8644, 6372|381.534|
|
|8832, 6704|8644, 6372|381.534|
|
||||||
|-1696, -16384|-1420, -16668|396.02|
|
|-1696, -16384|-1420, -16668|396.02|
|
||||||
|9040, 6352|8644, 6372|396.505|
|
|9040, 6352|8644, 6372|396.505|
|
||||||
|-19040, -7120|-19420, -6988|402.274|
|
|-19040, -7120|-19420, -6988|402.274|
|
||||||
|-5728, -656|-5356, -844|416.807|
|
|-5728, -656|-5356, -844|416.807|
|
||||||
|-7840, 208|-7884, 628|422.298|
|
|-7840, 208|-7884, 628|422.298|
|
||||||
|2800, -17648|2628, -17260|424.415|
|
|2800, -17648|2628, -17260|424.415|
|
||||||
|-20224, 416|-19980, 52|438.215|
|
|-20224, 416|-19980, 52|438.215|
|
||||||
|-14592, 3872|-14300, 3524|454.277|
|
|-14592, 3872|-14300, 3524|454.277|
|
||||||
|2400, -16864|2628, -17260|456.946|
|
|2400, -16864|2628, -17260|456.946|
|
||||||
|3952, 19632|3508, 19796|473.32|
|
|3952, 19632|3508, 19796|473.32|
|
||||||
|496, 19664|148, 19988|475.479|
|
|496, 19664|148, 19988|475.479|
|
||||||
|-544, -23648|-764, -23212|488.361|
|
|-544, -23648|-764, -23212|488.361|
|
||||||
|-272, -20576|-124, -21052|498.478|
|
|-272, -20576|-124, -21052|498.478|
|
||||||
|2160, -17088|2628, -17260|498.606|
|
|2160, -17088|2628, -17260|498.606|
|
||||||
|-720, 992|-812, 1492|508.394|
|
|-720, 992|-812, 1492|508.394|
|
||||||
|-19440, 3616|-19948, 3636|508.394|
|
|-19440, 3616|-19948, 3636|508.394|
|
||||||
|-10656, 4736|-10284, 4388|509.4|
|
|-10656, 4736|-10284, 4388|509.4|
|
||||||
|2800, 7504|2900, 6996|517.749|
|
|2800, 7504|2900, 6996|517.749|
|
||||||
|-7664, 7440|-7308, 7828|526.574|
|
|-7664, 7440|-7308, 7828|526.574|
|
||||||
|17904, -9952|17908, -10508|556.014|
|
|17904, -9952|17908, -10508|556.014|
|
||||||
|-20544, 0|-19980, 52|566.392|
|
|-20544, 0|-19980, 52|566.392|
|
||||||
|10608, 18096|10244, 17652|574.136|
|
|10608, 18096|10244, 17652|574.136|
|
||||||
|-18000, 1536|-17468, 1300|581.997|
|
|-18000, 1536|-17468, 1300|581.997|
|
||||||
|-20960, -3360|-20380, -3468|589.969|
|
|-20960, -3360|-20380, -3468|589.969|
|
||||||
|-720, -20960|-124, -21052|603.059|
|
|-720, -20960|-124, -21052|603.059|
|
||||||
|-14896, 3680|-14300, 3524|616.078|
|
|-14896, 3680|-14300, 3524|616.078|
|
||||||
|-18816, -6864|-19420, -6988|616.597|
|
|-18816, -6864|-19420, -6988|616.597|
|
||||||
|-14400, -768|-13772, -844|632.582|
|
|-14400, -768|-13772, -844|632.582|
|
||||||
|-19808, -6480|-19420, -6988|639.225|
|
|-19808, -6480|-19420, -6988|639.225|
|
||||||
|16160, 12848|15556, 13060|640.125|
|
|16160, 12848|15556, 13060|640.125|
|
||||||
|2096, -17632|2628, -17260|649.159|
|
|2096, -17632|2628, -17260|649.159|
|
||||||
|-19424, -304|-19980, 52|660.206|
|
|-19424, -304|-19980, 52|660.206|
|
||||||
|-14432, -912|-13772, -844|663.494|
|
|-14432, -912|-13772, -844|663.494|
|
||||||
|-640, -21488|-124, -21052|675.538|
|
|-640, -21488|-124, -21052|675.538|
|
||||||
|13840, -5632|13172, -5500|680.917|
|
|13840, -5632|13172, -5500|680.917|
|
||||||
|16240, 13056|15556, 13060|684.012|
|
|16240, 13056|15556, 13060|684.012|
|
||||||
|
|||||||
324
src/main.cu
324
src/main.cu
@@ -1,162 +1,162 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cuda_runtime.h>
|
#include <cuda_runtime.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
__global__ void find_nearest_B(
|
__global__ void find_nearest_B(
|
||||||
const float3 *__restrict__ A,
|
const float3 *__restrict__ A,
|
||||||
const float3 *__restrict__ B,
|
const float3 *__restrict__ B,
|
||||||
int *nearest_idx,
|
int *nearest_idx,
|
||||||
int N, int M)
|
int N, int M)
|
||||||
{
|
{
|
||||||
int idx = blockDim.x * blockIdx.x + threadIdx.x;
|
int idx = blockDim.x * blockIdx.x + threadIdx.x;
|
||||||
if (idx >= N)
|
if (idx >= N)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float3 a = A[idx];
|
float3 a = A[idx];
|
||||||
float min_dist = 1e30f;
|
float min_dist = 1e30f;
|
||||||
int min_j = -1;
|
int min_j = -1;
|
||||||
|
|
||||||
for (int j = 0; j < M; ++j)
|
for (int j = 0; j < M; ++j)
|
||||||
{
|
{
|
||||||
float dx = a.x - B[j].x;
|
float dx = a.x - B[j].x;
|
||||||
float dy = a.y - B[j].y;
|
float dy = a.y - B[j].y;
|
||||||
float dz = a.z - B[j].z;
|
float dz = a.z - B[j].z;
|
||||||
float dist = dx * dx + dy * dy + dz * dz;
|
float dist = dx * dx + dy * dy + dz * dz;
|
||||||
|
|
||||||
if (dist < min_dist)
|
if (dist < min_dist)
|
||||||
{
|
{
|
||||||
min_dist = dist;
|
min_dist = dist;
|
||||||
min_j = j;
|
min_j = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nearest_idx[idx] = min_j;
|
nearest_idx[idx] = min_j;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float3> load_coords_from_file(const std::string &filename)
|
std::vector<float3> load_coords_from_file(const std::string &filename)
|
||||||
{
|
{
|
||||||
std::vector<float3> coords;
|
std::vector<float3> coords;
|
||||||
std::ifstream file(filename);
|
std::ifstream file(filename);
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
std::cerr << "Unable to open file: " << filename << std::endl;
|
std::cerr << "Unable to open file: " << filename << std::endl;
|
||||||
return coords;
|
return coords;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(file, line))
|
while (std::getline(file, line))
|
||||||
{
|
{
|
||||||
std::istringstream iss(line);
|
std::istringstream iss(line);
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
if (iss >> x >> y >> z)
|
if (iss >> x >> y >> z)
|
||||||
{
|
{
|
||||||
coords.push_back(make_float3(x, y, z));
|
coords.push_back(make_float3(x, y, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return coords;
|
return coords;
|
||||||
}
|
}
|
||||||
|
|
||||||
void save_results_sorted(const std::string &filename,
|
void save_results_sorted(const std::string &filename,
|
||||||
const std::vector<float3> &h_A,
|
const std::vector<float3> &h_A,
|
||||||
const std::vector<float3> &h_B,
|
const std::vector<float3> &h_B,
|
||||||
const std::vector<int> &indices)
|
const std::vector<int> &indices)
|
||||||
{
|
{
|
||||||
struct Entry
|
struct Entry
|
||||||
{
|
{
|
||||||
float ax, az;
|
float ax, az;
|
||||||
float bx, bz;
|
float bx, bz;
|
||||||
float dist;
|
float dist;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Entry> entries;
|
std::vector<Entry> entries;
|
||||||
|
|
||||||
for (size_t i = 0; i < indices.size(); ++i)
|
for (size_t i = 0; i < indices.size(); ++i)
|
||||||
{
|
{
|
||||||
float3 a = h_A[i];
|
float3 a = h_A[i];
|
||||||
float3 b = h_B[indices[i]];
|
float3 b = h_B[indices[i]];
|
||||||
|
|
||||||
float dx = a.x - b.x;
|
float dx = a.x - b.x;
|
||||||
float dy = a.y - b.y;
|
float dy = a.y - b.y;
|
||||||
float dz = a.z - b.z;
|
float dz = a.z - b.z;
|
||||||
float dist = sqrtf(dx * dx + dy * dy + dz * dz);
|
float dist = sqrtf(dx * dx + dy * dy + dz * dz);
|
||||||
|
|
||||||
entries.push_back({a.x, a.z, b.x, b.z, dist});
|
entries.push_back({a.x, a.z, b.x, b.z, dist});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(entries.begin(), entries.end(), [](const Entry &e1, const Entry &e2)
|
std::sort(entries.begin(), entries.end(), [](const Entry &e1, const Entry &e2)
|
||||||
{ return e1.dist < e2.dist; });
|
{ return e1.dist < e2.dist; });
|
||||||
|
|
||||||
std::ofstream file(filename);
|
std::ofstream file(filename);
|
||||||
for (const auto &e : entries)
|
for (const auto &e : entries)
|
||||||
{
|
{
|
||||||
file << e.ax << " " << e.az << " "
|
file << e.ax << " " << e.az << " "
|
||||||
<< e.bx << " " << e.bz << " "
|
<< e.bx << " " << e.bz << " "
|
||||||
<< e.dist << std::endl;
|
<< e.dist << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
auto t_start = std::chrono::high_resolution_clock::now();
|
auto t_start = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
std::vector<float3> h_A = load_coords_from_file("data/cities.txt");
|
std::vector<float3> h_A = load_coords_from_file("data/cities.txt");
|
||||||
std::vector<float3> h_B = load_coords_from_file("data/strongholds.txt");
|
std::vector<float3> h_B = load_coords_from_file("data/strongholds.txt");
|
||||||
|
|
||||||
int N = h_A.size();
|
int N = h_A.size();
|
||||||
int M = h_B.size();
|
int M = h_B.size();
|
||||||
|
|
||||||
if (N == 0 || M == 0)
|
if (N == 0 || M == 0)
|
||||||
{
|
{
|
||||||
std::cerr << "Coords empty." << std::endl;
|
std::cerr << "Coords empty." << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 *d_A;
|
float3 *d_A;
|
||||||
float3 *d_B;
|
float3 *d_B;
|
||||||
int *d_nearest_idx;
|
int *d_nearest_idx;
|
||||||
cudaMalloc(&d_A, sizeof(float3) * N);
|
cudaMalloc(&d_A, sizeof(float3) * N);
|
||||||
cudaMalloc(&d_B, sizeof(float3) * M);
|
cudaMalloc(&d_B, sizeof(float3) * M);
|
||||||
cudaMalloc(&d_nearest_idx, sizeof(int) * N);
|
cudaMalloc(&d_nearest_idx, sizeof(int) * N);
|
||||||
|
|
||||||
cudaMemcpy(d_A, h_A.data(), sizeof(float3) * N, cudaMemcpyHostToDevice);
|
cudaMemcpy(d_A, h_A.data(), sizeof(float3) * N, cudaMemcpyHostToDevice);
|
||||||
cudaMemcpy(d_B, h_B.data(), sizeof(float3) * M, cudaMemcpyHostToDevice);
|
cudaMemcpy(d_B, h_B.data(), sizeof(float3) * M, cudaMemcpyHostToDevice);
|
||||||
|
|
||||||
int threads = 256;
|
int threads = 256;
|
||||||
int blocks = (N + threads - 1) / threads;
|
int blocks = (N + threads - 1) / threads;
|
||||||
|
|
||||||
// ✅ CUDA 커널 시간 측정 시작
|
// ✅ CUDA 커널 시간 측정 시작
|
||||||
cudaEvent_t start, stop;
|
cudaEvent_t start, stop;
|
||||||
cudaEventCreate(&start);
|
cudaEventCreate(&start);
|
||||||
cudaEventCreate(&stop);
|
cudaEventCreate(&stop);
|
||||||
cudaEventRecord(start);
|
cudaEventRecord(start);
|
||||||
|
|
||||||
find_nearest_B<<<blocks, threads>>>(d_A, d_B, d_nearest_idx, N, M);
|
find_nearest_B<<<blocks, threads>>>(d_A, d_B, d_nearest_idx, N, M);
|
||||||
|
|
||||||
cudaEventRecord(stop);
|
cudaEventRecord(stop);
|
||||||
cudaEventSynchronize(stop);
|
cudaEventSynchronize(stop);
|
||||||
float milliseconds = 0;
|
float milliseconds = 0;
|
||||||
cudaEventElapsedTime(&milliseconds, start, stop);
|
cudaEventElapsedTime(&milliseconds, start, stop);
|
||||||
std::cout << "CUDA kernel time: " << milliseconds << " ms" << std::endl;
|
std::cout << "CUDA kernel time: " << milliseconds << " ms" << std::endl;
|
||||||
|
|
||||||
std::vector<int> h_nearest_idx(N);
|
std::vector<int> h_nearest_idx(N);
|
||||||
cudaMemcpy(h_nearest_idx.data(), d_nearest_idx, sizeof(int) * N, cudaMemcpyDeviceToHost);
|
cudaMemcpy(h_nearest_idx.data(), d_nearest_idx, sizeof(int) * N, cudaMemcpyDeviceToHost);
|
||||||
|
|
||||||
save_results_sorted("output.txt", h_A, h_B, h_nearest_idx);
|
save_results_sorted("output.txt", h_A, h_B, h_nearest_idx);
|
||||||
|
|
||||||
cudaFree(d_A);
|
cudaFree(d_A);
|
||||||
cudaFree(d_B);
|
cudaFree(d_B);
|
||||||
cudaFree(d_nearest_idx);
|
cudaFree(d_nearest_idx);
|
||||||
|
|
||||||
auto t_end = std::chrono::high_resolution_clock::now();
|
auto t_end = std::chrono::high_resolution_clock::now();
|
||||||
std::chrono::duration<double> elapsed = t_end - t_start;
|
std::chrono::duration<double> elapsed = t_end - t_start;
|
||||||
std::cout << "Total time: " << elapsed.count() * 1000.0 << " ms" << std::endl;
|
std::cout << "Total time: " << elapsed.count() * 1000.0 << " ms" << std::endl;
|
||||||
|
|
||||||
std::cout << "Saved to output.txt." << std::endl;
|
std::cout << "Saved to output.txt." << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user