小编Edm*_*und的帖子

注册分配和溢出,简单方法?

我正在寻找一种方法来将局部变量分配给寄存器.我知道有几种严肃的方法(即维基百科上提到的方法),但我仍然坚持如何"溢出"完成.此外,相关文献相当令人生畏.我希望有一些更简单的东西可以满足我的优先事项:

  1. 正确性 - 一种算法,无论有多少局部变量,都会生成正确的代码.
  2. 简单 - 我无需阅读太多文献即可理解.
  3. 效率 - 它需要比现有方法更好,即:

将操作转换x = y # z为:

movl y, %eax
movl z, %ebx
op %ebx, %eax
movl %eax, x
Run Code Online (Sandbox Code Playgroud)

由于我的目标是英特尔386,因此一些相关的限制是:

  • 二进制操作有两个参数,其中一个是源和目标.一元操作只需一个参数.
  • 操作只能访问一个内存位置; 因此,二进制运算需要寄存器中至少有一个参数.
  • 最多有六个寄存器:%eax %ebx %ecx %edx %esi %edi.(%ebp也可作为最后手段.)
  • 有一些特殊情况,例如整数除法和返回寄存器,但我现在可以忽略它们.

编译器目前有三个步骤:

  • i386ification:所有操作都转换为表单a = a # b(或a = #a用于一元操作).
  • 活力分析:确定每个操作之前和之后的活变量集.
  • 寄存器分配:构建干扰图并着色.

然后编译器抛出它的蜡笔,不知道接下来该做什么.

public int mf(int cr, int ci) {
    int i = 0;
    int zr = 0;
    int zi = …
Run Code Online (Sandbox Code Playgroud)

compiler-theory graph-theory register-allocation i386

26
推荐指数
2
解决办法
7692
查看次数

自定义分配和Boehm GC

在我再次关闭的编译器项目中,我已经将闭包实现为具有可执行前缀的已分配内存.所以闭包是这样分配的:

c = make_closure(code_ptr, env_size, env_data);
Run Code Online (Sandbox Code Playgroud)

c 指向已分配内存块的指针,如下所示:

movl $closure_call, %eax
call *%eax
.align 4
; size of environment
; environment data
; pointer to closure code
Run Code Online (Sandbox Code Playgroud)

closure_call是一个辅助函数,它查看最近放在堆栈上的地址,并使用它来查找闭包数据和代码指针.Boehm GC用于一般内存管理,当不再引用闭包时,它可以由GC解除分配.

无论如何,这个分配的内存需要标记为可执行; 事实上,它跨越的整个页面都被标记出来.随着闭包的创建和释放,进程中越来越多的堆内存将是可执行的.

出于防御性编程的原因,我宁愿最小化可执行堆的数量.我的计划是尝试将所有闭包保存在同一页面上,并根据需要分配和释放可执行页面; 即为闭包实现自定义分配器.(如果所有闭包大小相同,这会更容易;因此第一步是将环境数据移动到可以正常管理的单独的非可执行分配中.这也使得防御性编程有意义.)

但剩下的问题是GC.Boehm已经做到了!我想要的是以某种方式告诉Boehm关于我的自定义分配,并让Boehm告诉我他们什么时候能够进行GC,但要让我自己解除分配.

所以我的问题是,Boehm中是否有钩子提供这样的自定义分配?

compiler-construction closures garbage-collection boehm-gc

9
推荐指数
1
解决办法
446
查看次数

在numpy中优化内存使用

下面的程序使用PyGame加载两个图像,将它们转换为Numpy数组,然后执行一些其他Numpy操作(例如FFT)以发出最终结果(少数几个).输入可能很大,但在任何时候只有一个或两个大对象应该是活的.

测试图像大约为10M像素,一旦灰度化就会转换为10MB.它被转换为dtype的Numpy数组uint8,经过一些处理(应用Hamming窗口),是一个dtype数组float64.以这种方式将两个图像加载到阵列中; 稍后的FFT步骤会产生一个dtype数组complex128.在添加过多gc.collect调用之前,程序存储器大小趋于随着每一步增加.此外,似乎大多数Numpy操作都会以最高的精度给出结果.

gc.collect在我的1GB Linux机器上运行测试(没有调用)导致长时间的颠簸,我没有等待.我还没有详细的内存使用统计信息 - 我尝试了一些Python模块和time命令无济于事; 现在我正在研究valgrind.观看PS(以及在测试的后期阶段处理机器无响应)表明最大内存使用量约为800 MB.

一个1000万单元的complex128阵列应该占用160 MB.(理想情况下)最多有两个这样的活动,加上非实质性的Python和Numpy库以及其他随身用品,可能意味着允许500 MB.

我可以想到两个角度来解决这个问题:

  • 尽快丢弃中间阵列.这就是所gc.collect要求的 - 他们似乎已经改善了这种情况,因为它现在只用几分钟的捶打就完成了;-).我认为可以预期像Python这样的语言中的内存密集型编程需要一些人工干预.

  • 在每一步使用不太精确的Numpy数组.不幸的是,返回数组的操作fft2似乎不允许指定类型.

所以我的主要问题是:有没有办法在Numpy数组操作中指定输出精度?

更一般地说,使用Numpy时还有其他常见的内存保存技术吗?

另外,Numpy有更多惯用的释放阵列内存的方法吗?(我想这会让数组对象在Python中生存,但处于不可用的状态.)显式删除后立即GC会感觉很乱.

import sys
import numpy
import pygame
import gc


def get_image_data(filename):
    im = pygame.image.load(filename)
    im2 = im.convert(8)
    a = pygame.surfarray.array2d(im2)
    hw1 = numpy.hamming(a.shape[0])
    hw2 = numpy.hamming(a.shape[1])
    a = a.transpose()
    a = a*hw1
    a = a.transpose()
    a = a*hw2
    return a


def check():
    gc.collect()
    print 'check' …
Run Code Online (Sandbox Code Playgroud)

python pygame memory-management numpy

8
推荐指数
1
解决办法
4438
查看次数

为什么不承诺Scheme中的数据类型?

delayScheme中返回的对象是"承诺",但承诺不被视为类型(因此没有promise?过程,并且它未在R5RS或R6RS中列为类型).

有这么强烈的共鸣吗?例如(if (promise? x) (force x) x),对我来说,做一些事情似乎很自然.(我看到一些实现会让我强迫非承诺,而其他实现则不会).此外,如果我可以存储一个变量并传递它,我觉得它应该有一个类型.

scheme lazy-evaluation

6
推荐指数
1
解决办法
346
查看次数

数组在PostgreSQL中都是NULL

如果PostgreSQL数组的所有元素都为NULL,是否有一个返回TRUE的表达式?

如果它是一个非NULL的值,我当然可以使用类似的东西:

SELECT 4 = ALL (ARRAY[4,5]::integer[]);
Run Code Online (Sandbox Code Playgroud)

但是我想用IS NULL测试而不是= 4测试来进行ALL操作.我不认为这有一个ALL语法,并且NULL周围的语义与数组复合我自己无法想到实现它的形式.因此我问Stack Overflow.;-)

我知道我可以在pl/sql或pl/pgsql中编写一个函数来执行此操作,但是我想在使用它之前看看是否有直接表达式.

sql arrays postgresql null

6
推荐指数
2
解决办法
5272
查看次数

通过一个带有void*的C接口传递shared_ptr

我有一个使用SDL的C++项目,特别是SDL事件.我想将事件系统用于传入的网络消息,就像它用于UI事件一样.我可以定义一个新的事件类型并附加一些任意数据(参见这个例子).如果我使用普通指针,这就是我要做的事情:

Uint32 message_event_type = SDL_RegisterEvents(1);

/* In the main event loop */
while (SDL_Poll(&evt)) {
    if (evt.type == message_event_type) {
         Message *msg = evt.user.data1;
         handle_message(msg);
    }
}

/* Networking code, possibly in another thread */
Message *msg = read_message_from_network();
SDL_Event evt;
evt.type = message_event_type;
evt.user.data1 = msg;
SDL_PostEvent(evt);
Run Code Online (Sandbox Code Playgroud)

相反,我一直在使用shared_ptr<Message>.消息一旦构造就是只读对象,并且在处理时可能在很多地方使用,所以我想为它们使用shared_ptr.

我想将shared_ptr用于网络端的消息,也可以在事件处理端使用.如果我这样做:

// in networking code:
shared_ptr<Message> msg = ...
evt.user.data1 = msg.get();

// later, in event handling:
shared_ptr<Message> msg(evt.user.data1);
Run Code Online (Sandbox Code Playgroud)

然后有两个独立的shared_ptrs,任何一个都可以删除Message对象,而其中一个仍在使用它.我需要以某种方式通过SDL_UserEvent结构传递shared_ptr,该结构只有几个void *和int字段.

额外.注意 …

c++ sdl shared-ptr

6
推荐指数
2
解决办法
1201
查看次数

使用Malloc Hooks

我试图使用malloc钩子来创建自定义函数my_malloc().在我的主程序中,当我调用malloc()时我希望它调用my_malloc()可以有人请给我一个如何在C中执行此操作的示例

c malloc

5
推荐指数
3
解决办法
9285
查看次数

创建导致字符串的FILE*流

我正在寻找一种方法来传递一个FILE *函数,以便函数可以写入它fprintf.如果我想让输出在磁盘上的实际文件中出现,这很容易.但我想要的是将所有输出作为字符串(char *).我喜欢的那种API是:

/** Create a FILE object that will direct writes into an in-memory buffer. */
FILE *open_string_buffer(void);

/** Get the combined string contents of a FILE created with open_string_buffer
    (result will be allocated using malloc). */
char *get_string_buffer(FILE *buf);

/* Sample usage. */
FILE *buf;
buf = open_string_buffer();
do_some_stuff(buf);   /* do_some_stuff will use fprintf to write to buf */
char *str = get_string_buffer(buf);
fclose(buf);
free(str);
Run Code Online (Sandbox Code Playgroud)

glibc的头似乎表明,一个文件可能被设置了挂钩函数来执行实际的读写.在我的情况下,我想我希望写钩子将字符串的副本附加到链表,并且有一个get_string_buffer函数可以计算出列表的总长度,为它分配内存,然后将每个项目复制到它在正确的地方.

我的目标是可以传递给函数的东西,比如do_some_stuff …

c string printf file stream

5
推荐指数
1
解决办法
1890
查看次数

java垃圾回收

我在SCJP准备网站上经历了这个问题.答案A如何正确?

a,b,aa在标有"// some code goes here"的行引用的对象的真实情况是什么?

class A {
    private B b;
    public A() {
        this.b = new B(this);
    }
}

class B {
    private A a;
    public B(A a) {
        this.a = a;
    }
}

public class Test { 
    public static void main(String args[]) {
        A aa = new A();
        aa = null;
        // some code goes here
    }
}


A) The objects referenced by a and b are eligible for garbage collection.
B) None of these objects are …
Run Code Online (Sandbox Code Playgroud)

java garbage-collection

5
推荐指数
1
解决办法
596
查看次数

在Prolog中满足一系列目标

在Prolog中,我经常通过提供模板(包含变量的结构)然后满足一组约束来解决问题.一个简单的例子可能是:

go(T) :-
    T = [_, _, _],
    member(cat, T),
    member(dog, T),
    member(mouse, T).
Run Code Online (Sandbox Code Playgroud)

实际上,约束集是以其他方式生成的,而不是被修复,我必须编写一个递归谓词来依次满足每个约束:

go(T) :-
    T = [_, _, _],
    findall(A, animal(A), As),
    % satisy member(A, T) for each A in As
    fill_in_animals(T, As)

fill_in_animals(T, []).
fill_in_animals(T, [A|Rest]) :-
    member(A, T),
    fill_in_animals(T, Rest).
Run Code Online (Sandbox Code Playgroud)

请注意,我的问题不是与列表相关的约束,甚至参数也不能总是容易地生成为要传递给上面使用的相对简单的辅助谓词的列表.在实践中,我发现助手是我每次写的一个相当笨拙的谓词,其中:

  1. 接受一个模板,几个用于约束的参数(因此用于将模板的变量绑定到有用的值),以及一个用于指示它最多的约束的变量.
  2. 生成约束以在此迭代中满足,将其应用于模板.
  3. 递归调用自身,以便可以满足剩余的约束.

我正在寻找的是一个基于findall等等的谓词,它将一个接一个地满足一系列目标.就像是:

% satisfyall(:Goal)
% backtracks on Goal but keeps all bindings from each fully satisfied goal.

satisfyall((animal(A), member(A, T)))
Run Code Online (Sandbox Code Playgroud)

我正在寻找的答案不一定是这种形式.实际上,在回溯目标和维护由此产生的每组绑定之间可能存在矛盾.

我希望我已经解释了我的问题,以便能够帮助我们.(如果不让我知道的话.)为这个冗长的问题提前道歉!

更新(2年后)

我会在今天晚些时候试一试并更新我的问题!

请注意,我从未说过我会在尝试的同一天更新问题. ;-)

@CapelliC引导我朝着正确的方向前进,我发现了一种似乎运作良好的模式:

?- Gs = …
Run Code Online (Sandbox Code Playgroud)

prolog

5
推荐指数
1
解决办法
795
查看次数