- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个 C 代码,我想翻译该代码以使用 CUDA。
解释完整的问题会非常复杂和冗长,这就是我遇到问题的一部分。
现在的问题是:我需要创建四棵 AVL 树(要插入树中的数据是从文件中读取的(实际文件,较小的文件,有 255000 行,但最多可以有 1200 万行). 在每棵对应的树上插入四个值后,不同树的每个节点都会有一个不同节点的列表(每棵树一个不同)但首先我需要解决我遇到的问题。
问题如下,如果我创建其中三个没有问题,但如果我创建四个,CUDA 会给出错误“内存不足”。
请注意,有 410 行代码,函数 cudaMallocManaged(...) 的内存保留位于以下行:90(函数 main)和 164、176 和 190(函数 auxCrearIndiceAVL)。所以我认为它有错误,但如果是这样我就看不到了。
此外,我还在一台装有 Visual Studio 的 Windows 计算机上工作,该计算机配备两个 NVIDIA 680 GTX (2 GB) 和 32 GB 内存。因此,对于这 4 个结构,我认为这些结构有足够的内存。我不知道是否需要激活 CUDA 设置或 ...
提前感谢所有关注此内容的人。曼努埃尔·路易斯·阿斯纳尔
代码如下:
#include "cuda_runtime.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define TRUE 1
#define FALSE 0
#define CHECK(r) {_check((r), __LINE__);}
/* Estructuras y tipos */
enum { IZQUIERDO, DERECHO };
typedef struct _nodo_especial {
double m2i;
double m1o;
double m2o;
struct _tipo_nodo *dato_next_index;
struct _nodo_especial *siguiente;
struct _nodo_especial *next_index;
} nodoEspecial;
typedef nodoEspecial* pNodoEspecial;
typedef struct _tipo_nodo {
double dato;
int FE;
struct _nodo_especial *list;
struct _tipo_nodo *derecho;
struct _tipo_nodo *izquierdo;
struct _tipo_nodo *padre;
} tipoNodo;
typedef tipoNodo* pNodo;
typedef tipoNodo* Arbol;
typedef struct REGcrowd {
double m1i, m2i, m1o, m2o, x, y, color; // crowding
} EstrellaCrowding;
typedef EstrellaCrowding* pEstrellaCrowding;
typedef EstrellaCrowding* ListaEstrellasCrowding;
typedef struct _nodo_recubrimiento {
double dato;
pNodo enlace;
} nodoRecubrimiento;
typedef nodoRecubrimiento* pNodoRecubrimiento;
typedef nodoRecubrimiento* ListaRecubrimiento;
typedef struct _indices {
Arbol indiceM1i, indiceColor, indiceX, indiceY;
int numeroEstrellasIndice;
int numeroNodosM1i, numeroNodosColor, numeroNodosX, numeroNodosY;
ListaRecubrimiento listaRecubrimiento;
} tipoIndice;
typedef tipoIndice* Indice;
typedef tipoIndice* pIndice;
pNodo auxCrearIndiceAVL(Arbol *a, double dat, int *contador);
__global__ void kernel(Indice indice);
void _check(cudaError_t r, int line);
void check_memory_cuda(void);
__host__ __device__ void InOrden(Arbol a, int *contador);
/* Funciones de equilibrado */
void Equilibrar(Arbol *a, pNodo nodo, int rama, int nuevo);
void RSI(Arbol *raiz, pNodo nodo);
void RSD(Arbol *raiz, pNodo nodo);
void RDI(Arbol *raiz, pNodo nodo);
void RDD(Arbol *raiz, pNodo nodo);
int Vacio(Arbol r);
int main(int argc, char *argv[]) {
check_memory_cuda();
//Indice indice = (pIndice)malloc(sizeof(tipoIndice));
Indice indice;
CHECK(cudaMallocManaged(&indice, sizeof(Indice)));
indice->indiceM1i = NULL;
indice->indiceColor = NULL;
indice->indiceX = NULL;
indice->indiceY = NULL;
indice->listaRecubrimiento = NULL;
indice->numeroEstrellasIndice = 0;
indice->numeroNodosM1i = 0;
indice->numeroNodosColor = 0;
indice->numeroNodosX = 0;
indice->numeroNodosY = 0;
FILE *fcrowd;
int i;
EstrellaCrowding estrellaCrowding;
fcrowd = fopen(argv[1], "r");
for (i = 0; !feof(fcrowd); i++) {
fscanf(fcrowd, "%lf %lf %lf %lf %lf %lf", &estrellaCrowding.m1i, &estrellaCrowding.m2i, &estrellaCrowding.m1o, &estrellaCrowding.m2o, &estrellaCrowding.x, &estrellaCrowding.y);
estrellaCrowding.color = estrellaCrowding.m1i - estrellaCrowding.m2i;
pNodo auxM1i = auxCrearIndiceAVL(&indice->indiceM1i, estrellaCrowding.m1i, &indice->numeroNodosM1i);
pNodo auxColor = auxCrearIndiceAVL(&indice->indiceColor, estrellaCrowding.color, &indice->numeroNodosColor);
pNodo auxX = auxCrearIndiceAVL(&indice->indiceX, estrellaCrowding.x, &indice->numeroNodosX);
//pNodo auxY = auxCrearIndiceAVL(&indice->indiceY, estrellaCrowding.y, &indice->numeroNodosY);
}
fclose(fcrowd);
check_memory_cuda();
printf("Imprimiendo el recorrido en InOrden del arbol M1i CPU\n");
int contador = 0;
InOrden(indice->indiceM1i, &contador);
printf("El numero de nodos del arbol M1i es CPU: %d\n", indice->numeroNodosM1i);
printf("Raiz arbol M1i CPU: %lf\n", indice->indiceM1i->dato);
printf("El numero de nodos del arbol Color es CPU: %d\n", indice->numeroNodosColor);
printf("Raiz arbol Color CPU: %lf\n", indice->indiceColor->dato);
printf("El numero de nodos del arbol X es CPU: %d\n", indice->numeroNodosX);
printf("Raiz arbol X CPU: %lf\n", indice->indiceX->dato);
//printf("El numero de nodos del arbol Y es CPU: %d\n", indice->numeroNodosY);
//printf("Raiz arbol Y CPU: %lf\n", indice->indiceY->dato);
kernel<<<1, 1>>>(indice);
cudaDeviceSynchronize();
return 0;
}
pNodo auxCrearIndiceAVL(Arbol *a, double dat, int *contador) {
pNodo padre = NULL;
pNodo actual = *a;
/* Buscar el dato en el arbol, manteniendo un puntero al nodo padre */
while (!Vacio(actual) && dat != actual->dato) {
padre = actual;
if (dat < actual->dato)
actual = actual->izquierdo;
else if (dat > actual->dato)
actual = actual->derecho;
}
/* Si se ha encontrado el elemento, regresar sin insertar */
if (!Vacio(actual))
return actual;
/* Si padre es NULL, entonces el arbol estaba vacio, el nuevo nodo sera el nodo raiz */
else if (Vacio(padre)) {
//(*a) = (Arbol)malloc(sizeof(tipoNodo));
CHECK(cudaMallocManaged(&(*a), sizeof(tipoNodo), cudaMemAttachGlobal));
(*a)->dato = dat;
(*a)->izquierdo = (*a)->derecho = NULL;
(*a)->padre = NULL;
(*a)->FE = 0;
(*a)->list = NULL;
(*contador)++;
return (*a);
}
/* Si el dato es menor que el que contiene el nodo padre, lo insertamos en la rama izquierda */
else if (dat < padre->dato) {
//actual = (Arbol)malloc(sizeof(tipoNodo));
CHECK(cudaMallocManaged(&actual, sizeof(tipoNodo), cudaMemAttachGlobal));
padre->izquierdo = actual;
actual->dato = dat;
actual->izquierdo = actual->derecho = NULL;
actual->padre = padre;
actual->FE = 0;
actual->list = NULL;
Equilibrar(a, padre, IZQUIERDO, TRUE);
(*contador)++;
return actual;
}
/* Si el dato es mayor que el que contiene el nodo padre, lo insertamos en la rama derecha */
else { /*if (dat > padre->dato) */
//actual = (Arbol)malloc(sizeof(tipoNodo));
CHECK(cudaMallocManaged(&actual, sizeof(tipoNodo), cudaMemAttachGlobal));
padre->derecho = actual;
actual->dato = dat;
actual->izquierdo = actual->derecho = NULL;
actual->padre = padre;
actual->FE = 0;
actual->list = NULL;
Equilibrar(a, padre, DERECHO, TRUE);
(*contador)++;
return actual;
}
}
__global__ void kernel(Indice indice) {
printf("Imprimiendo el recorrido en InOrden del arbol M1i GPU\n");
int contador = 0;
InOrden(indice->indiceM1i, &contador);
printf("El numero de nodos del arbol M1i es GPU: %d\n", indice->numeroNodosM1i);
printf("Raiz arbol M1i GPU: %lf\n", indice->indiceM1i->dato);
printf("El numero de nodos del arbol Color es GPU: %d\n", indice->numeroNodosColor);
printf("Raiz arbol Color GPU: %lf\n", indice->indiceColor->dato);
printf("El numero de nodos del arbol X es GPU: %d\n", indice->numeroNodosX);
printf("Raiz arbol X GPU: %lf\n", indice->indiceX->dato);
//printf("El numero de nodos del arbol Y es GPU: %d\n", indice->numeroNodosY);
//printf("Raiz arbol Y GPU: %lf\n", indice->indiceY->dato);
}
void _check(cudaError_t r, int line) {
if (r != cudaSuccess) {
printf("CUDA error on line %d: %s\n", line, cudaGetErrorString(r), line);
exit(0);
}
}
void check_memory_cuda(void) {
size_t free, total;
cudaMemGetInfo(&free, &total);
printf("CUDA Memory:\n\tFree ---> %llu\n\tTotal ----> %llu\n", free, total);
}
/* Recorrido de arbol en inorden, aplicamos la funcion func, que tiene
el prototipo:
void func(double*);
*/
__host__ __device__ void InOrden(Arbol a, int *contador)
{
if (a->izquierdo) InOrden(a->izquierdo, contador);
printf("%d ---> %lf\n", *contador, a->dato);
(*contador)++;
if (a->derecho) InOrden(a->derecho, contador);
}
/* Equilibrar árbol AVL partiendo del nodo nuevo */
void Equilibrar(Arbol *a, pNodo nodo, int rama, int nuevo)
{
int salir = FALSE;
/* Recorrer camino inverso actualizando valores de FE: */
while (nodo && !salir) {
if (nuevo)
if (rama == IZQUIERDO) nodo->FE--; /* Depende de si añadimos ... */
else nodo->FE++;
else
if (rama == IZQUIERDO) nodo->FE++; /* ... o borramos */
else nodo->FE--;
if (nodo->FE == 0) salir = TRUE; /* La altura de las rama que
empieza en nodo no ha variado,
salir de Equilibrar */
else if (nodo->FE == -2) { /* Rotar a derechas y salir: */
if (nodo->izquierdo->FE == 1) RDD(a, nodo); /* Rotación doble */
else RSD(a, nodo); /* Rotación simple */
salir = TRUE;
}
else if (nodo->FE == 2) { /* Rotar a izquierdas y salir: */
if (nodo->derecho->FE == -1) RDI(a, nodo); /* Rotación doble */
else RSI(a, nodo); /* Rotación simple */
salir = TRUE;
}
if (nodo->padre)
if (nodo->padre->derecho == nodo) rama = DERECHO; else rama = IZQUIERDO;
nodo = nodo->padre; /* Calcular FE, siguiente nodo del camino. */
}
}
/* Rotación doble a derechas */
void RDD(Arbol *raiz, Arbol nodo)
{
pNodo Padre = nodo->padre;
pNodo P = nodo;
pNodo Q = P->izquierdo;
pNodo R = Q->derecho;
pNodo B = R->izquierdo;
pNodo C = R->derecho;
if (Padre)
if (Padre->derecho == nodo) Padre->derecho = R;
else Padre->izquierdo = R;
else *raiz = R;
/* Reconstruir árbol: */
Q->derecho = B;
P->izquierdo = C;
R->izquierdo = Q;
R->derecho = P;
/* Reasignar padres: */
R->padre = Padre;
P->padre = Q->padre = R;
if (B) B->padre = Q;
if (C) C->padre = P;
/* Ajustar valores de FE: */
switch (R->FE) {
case -1: Q->FE = 0; P->FE = 1; break;
case 0: Q->FE = 0; P->FE = 0; break;
case 1: Q->FE = -1; P->FE = 0; break;
}
R->FE = 0;
}
/* Rotación doble a izquierdas */
void RDI(Arbol *a, pNodo nodo)
{
pNodo Padre = nodo->padre;
pNodo P = nodo;
pNodo Q = P->derecho;
pNodo R = Q->izquierdo;
pNodo B = R->izquierdo;
pNodo C = R->derecho;
if (Padre)
if (Padre->derecho == nodo) Padre->derecho = R;
else Padre->izquierdo = R;
else *a = R;
/* Reconstruir árbol: */
P->derecho = B;
Q->izquierdo = C;
R->izquierdo = P;
R->derecho = Q;
/* Reasignar padres: */
R->padre = Padre;
P->padre = Q->padre = R;
if (B) B->padre = P;
if (C) C->padre = Q;
/* Ajustar valores de FE: */
switch (R->FE) {
case -1: P->FE = 0; Q->FE = 1; break;
case 0: P->FE = 0; Q->FE = 0; break;
case 1: P->FE = -1; Q->FE = 0; break;
}
R->FE = 0;
}
/* Rotación simple a derechas */
void RSD(Arbol *a, pNodo nodo)
{
pNodo Padre = nodo->padre;
pNodo P = nodo;
pNodo Q = P->izquierdo;
pNodo B = Q->derecho;
if (Padre)
if (Padre->derecho == P) Padre->derecho = Q;
else Padre->izquierdo = Q;
else *a = Q;
/* Reconstruir árbol: */
P->izquierdo = B;
Q->derecho = P;
/* Reasignar padres: */
P->padre = Q;
if (B) B->padre = P;
Q->padre = Padre;
/* Ajustar valores de FE: */
P->FE = 0;
Q->FE = 0;
}
/* Rotación simple a izquierdas */
void RSI(Arbol *a, pNodo nodo)
{
pNodo Padre = nodo->padre;
pNodo P = nodo;
pNodo Q = P->derecho;
pNodo B = Q->izquierdo;
if (Padre)
if (Padre->derecho == P) Padre->derecho = Q;
else Padre->izquierdo = Q;
else *a = Q;
/* Reconstruir árbol: */
P->derecho = B;
Q->izquierdo = P;
/* Reasignar padres: */
P->padre = Q;
if (B) B->padre = P;
Q->padre = Padre;
/* Ajustar valores de FE: */
P->FE = 0;
Q->FE = 0;
}
/* Comprobar si un árbol es vacío */
int Vacio(Arbol r)
{
return r == NULL;
}
最佳答案
昨天晚上我正在做一些 cudaMallocManaged(...) 测试,在此之前我认为统一内存正在使用设备内存,当设备空间不足时,它们开始使用主机内存。
事实并非如此,使用 CUDA 6 统一内存系统 cudaMallocManaged(...),我们只能分配设备拥有的内存。
非常感谢ArchaeaSoftware 的回答
感谢全民阅读,希望大家尽可能多地享受 CUDA
伙计们,待会儿见。曼纽尔
关于c - 使用 cudaMallocManaged 很快就会耗尽内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28159219/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!