3

I am writing a GPU database and looking at using javascript as language to query against using node.js.

I have been writing a node addon as I have written the GPU database in C++. However I have problem with my node.js addon as my c++ objects are not being destructed but only when I am not explicitly using the new operator. If I am using the new operator, it's fine, it's just when a call a method that creates a new method - like copy(), etc. I am using V8::AdjustAmountOfExternalAllocatedMemory(size()) as indication to V8 that I have allocated exernal memory (on the GPU).

Please could I get some advice.

1. Code that correctly frees GPU memory

This piece of code correctly frees the GPU memory by calling the object destructor, which makes a call to free the GPU memory:

var gpudb = require('./build/Release/gpudb');

var n = 1000000;
for (var i = 0; i < 10000; ++i) {
    var col = new gpudb.GpuArray(n);
}

2. However, this piece of code doesn't call the objects' destructor to free GPU memory.

var gpudb = require('./build/Release/gpudb');

var n = 1000000;
var col = new gpudb.GpuArray(n);
for (var i = 0; i < 10000; ++i) {
        var copyOfCol = col.copy();
}

3. Now, here's the functions for the constructor and copy function respectively.

Handle<Value> GpuVector::New(const Arguments& args) {
  HandleScope scope;

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new GpuVector(...)`
    int value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    GpuVector* obj = new GpuVector(value);
    obj->Wrap(args.This());
    return args.This();
  } else {
    // Invoked as plain function `GpuVector(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    return scope.Close(constructor->NewInstance(argc, argv));
  }
}

Handle<Value> GpuArray::Copy(const Arguments& args) {
    HandleScope scope;

    GpuArray* in = ObjectWrap::Unwrap<GpuVector>(args.This());
    GpuArray* out = new GpuArray(in); // creates new gpu memory slot and copies the data over

    out->Wrap(args.This());
    return args.This();
}
4

1 回答 1

0

如果没有 GpuArray 构造函数,就很难判断出了什么问题。

但是我可以看到一些不正确的东西:

Handle<Value> GpuArray::Copy(const Arguments& args) {
    //...
    GpuArray* in = ObjectWrap::Unwrap<GpuVector>(args.This());

    //...
}

您正在GpuVector从一个对象中解开一个对象GpuArray,这是错误的。

Wrap/Unwrap 方法应该用于在 c++ 对象和它们各自的 js 对象之间建立连接,而不是在不同的对象之间建立连接。

从您发布的代码看来(但我可能错了)您正在尝试克隆该对象,如果我是正确的,应该这样做:

Handle<Value> GpuArray::Copy(const Arguments& args) {
    HandleScope scope;

    GpuArray* in = ObjectWrap::Unwrap<GpuArray>( args.This() );

    //build argc and argv here

    Local<Object> outJs = constructorOfGpuArray->NewInstance( argc, argv );
    GpuArray* out = ObjectWrap::Unwrap<GpuArray>( outJs );

    //set members/etc of the "out" object so it looks identical to the "in" object

    //return the js object to the caller.
    return scope.Close( outJs );
}

我没有测试代码,但理论上它应该可以工作。

于 2015-02-26T03:05:35.190 回答