Я делаю программу, которая читает из входных данных два числа, N и K, затем читает N целых чисел и сохраняет их в массив.Цель программы состоит в том, чтобы вычислить максимальное среднее значение всех сегментов длиной не менее K. Затем она печатает это среднее значение (умноженное на 1000 и усекающее десятичные знаки).
Это задача в соревновании по программированию. Iучаствовал один раз, и существует решение O (n log (n)) для этой проблемы.Тем не менее, я думаю, что использование графической карты вместо процессора должно быть достаточно для решения O (n ^ 2) с использованием памяти O (n).По какой-то причине, хотя, когда я достигаю входов около 90 000, программа завершает работу с исключением шины.
#include <bits/stdc++.h>
using namespace std;
__global__
void solve(int n, int k, int *a, int *x) {
// i is the beginning of the segment
for (int i = threadIdx.x; i < n; i += blockDim.x) {
int sum = 0;
// j is the end of the segment
for (int j = i; j < n; j++) {
sum = sum + a[j];
if (j-i+1 >= k && x[threadIdx.x] < sum * 1000ll / (j-i+1))
x[threadIdx.x] = sum * 1000ll / (j-i+1);
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
// n = number of elements, k = minimum segment length, T = number of threads
int n, k, T = 256;
cin >> n >> k;
// a = input array, x = array of results (one for each thread, so no two threads write to the same place at the same time)
int *a, *x;
// https://devblogs.nvidia.com/even-easier-introduction-cuda/ here I just copy their approach
cudaMallocManaged(&a, n*sizeof(int));
cudaMallocManaged(&x, T*sizeof(int));
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i < T; i++)
x[i] = 0;
solve<<<1, T>>>(n, k, a, x);
cudaDeviceSynchronize();
// the result is the maximum of all results
int res = 0;
for (int i = 0; i < T; i++)
res = max(res, x[i]);
cout << res << endl;
cudaFree(a);
cudaFree(x);
return 0;
}
Я попытался выяснить, где именно происходит ошибка, и из того, что я могу сказать, программа вылетает.здесь:
for (int i = 0; i < T; i++)
res = max(res, x[i]);
Когда программа пытается получить доступ к любому значению в x, происходит сбой.Если я закомментирую это для цикла, он завершается нормально.Я проверил адреса указателей в x, и они не равны нулю.
Программа отлично работает для входных массивов длиной <= 30 000. Это может означать, что я выделяю слишком много памяти, однако могупросто запустите эту программу с элементами 1e7 (скопировано из еще более простого введения).</p>
#include <iostream>
#include <math.h>
// Kernel function to add the elements of two arrays
__global__
void add(int n, float *x, float *y)
{
for (int i = 0; i < n; i++)
y[i] = x[i] + y[i];
}
int main(void)
{
int N = 1<<20;
float *x, *y;
// Allocate Unified Memory – accessible from CPU or GPU
cudaMallocManaged(&x, N*sizeof(float));
cudaMallocManaged(&y, N*sizeof(float));
// initialize x and y arrays on the host
for (int i = 0; i < N; i++) {
x[i] = 1.0f;
y[i] = 2.0f;
}
// Run kernel on 1M elements on the GPU
add<<<1, 1>>>(N, x, y);
// Wait for GPU to finish before accessing on host
cudaDeviceSynchronize();
// Check for errors (all values should be 3.0f)
float maxError = 0.0f;
for (int i = 0; i < N; i++)
maxError = fmax(maxError, fabs(y[i]-3.0f));
std::cout << "Max error: " << maxError << std::endl;
// Free memory
cudaFree(x);
cudaFree(y);
return 0;
}
Моя видеокарта 750M.