小编joe*_*joe的帖子

在字节码编译器中计算跳转地址的智能解决方案?

假设我正在实现一个字节码编译器,类似于Lua的/ Python ......等等.

我正在遍历AST,生成字节码指令,并且我遇到了循环break内部的if-else内部while:

while (cond1)
    if (cond2)
        ...
    else
        break
Run Code Online (Sandbox Code Playgroud)

(我尝试写出等效的字节码,但它看起来并没有太大帮助.)

关键是,该示例中至少有4个"跳转"指令,我想找到一个优雅的解决方案来填充跳转地址,因为我编译AST ...我不知道while循环的跳转地址或者break直到我完全"编译"内部陈述之后.

  1. 伪代码解决方案是理想的
  2. 解决方案不应该取决于我是否实现了基于寄存器或堆栈的字节码编译器(我正在使用它们)

我还没读这本龙书.

如果我递归地编译AST,当我break在一些任意数量的循环和if-else块中找到一个语句时,编译器应该如何知道跳转到哪个空标签?我猜测递归AST行走函数外部的某种类型的标签名称堆栈.

compiler-construction bytecode

7
推荐指数
1
解决办法
445
查看次数

Java"分层队列"实现快速生产者,减缓消费者

我有一个生产者 - 消费者场景,生产者生产的速度比消费者消费的快得多.通常,解决方案是使生产者阻止,因为生产者/消费者场景的运行速度与最慢的组件一样快.限制或阻止生产者并不是一个好的解决方案,因为我们的应用程序为消费者提供了足够的时间来赶上.

这是一个图表,描绘了我们的应用程序中的完整"阶段"与更常见的场景:

      Our Application                 Common Scenario
 2N +--------+--------+
    |PPPPPPPP|oooooooo|                                         P = Producer
    |PPPPPPPP|oooooooo|                                         C = Consumer
  N +--------+--------+      N +--------+--------+--------+     o = Other Work
    |CPCPCPCP|CCCCCCCC|        |CPCPCPCP|CPCPCPCP|oooooooo|     N = number of tasks
    |CPCPCPCP|CCCCCCCC|        |CPCPCPCP|CPCPCPCP|oooooooo|
    -------------------        ----------------------------
    0       T/2       T        0       T/2       T      3T/2
Run Code Online (Sandbox Code Playgroud)

我们的想法是通过不抑制生产者来最大化吞吐量.

我们的任务运行的数据很容易被序列化,因此我计划实现一个文件系统解决方案,以便溢出所有无法立即满足的任务.

我正在使用具有最大容量的Java ThreadPoolExecutor,BlockingQueue以确保我们不会耗尽内存.问题是在实施这样的"分层"的队列,在那里是可以在内存中排队的任务是如此立即执行,否则数据被排队在磁盘上.

我想出了两个可能的解决方案:

  1. 实现一个BlockingQueue从无到有,使用LinkedBlockingQueueArrayBlockingQueue实施作为参考.这可能就像在标准库中复制实现并添加文件系统读/写一样简单.
  2. 继续使用标准的BlockingQueue实施,实现一个独立的FilesystemQueue存储我的数据,并使用一个或多个线程出列文件,创建RunnableS和使用他们排队ThreadPoolExecutor.

这些都是合理的,是否有更好的方法?

java queue concurrency multithreading threadpool

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

如何包含相同标题的两个不同版本?

我正在将文件转换代码从专有文件格式写入一个更通用的.我的目标是支持制造商文件格式的多个版本.

我有相同专有标头的多个版本.标题定义了构成主文件头的各种结构(文件只是一个大标题,后跟原始数据).

我需要读取源文件的前4个字节来确定文件版本.反过来,文件版本告诉我使用哪个版本的C-structs来创建文件.

问题是:

  1. 我无法修改专有标头
  2. 标头不使用名称空间或类
  3. 标题中定义了一些很好的宏

可能的解决方案:

  • 为每个文件版本类型构建不同的转换器二进制文件:-(
    • 对用户和开发人员来说都不方便
  • 为每个版本动态加载库
    • 转换器是面向插件的,因此已经发生了很多这样的事情

我尝试过使用命名空间进行黑客攻击:

namespace version1 {
    #include "version1.h"
}

namespace version2 {
    #include "version2.h"
}

int main (void) {
    version1::header *hdr = new version1::header;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但这不会起作用,因为包括警卫,并且因为在每个标题中重新定义了多个宏.

有一种优雅的方式来处理这个问题吗?

c++ conflict header version include

3
推荐指数
1
解决办法
2313
查看次数

在可变参数化模板函数中为每种模板类型调用void函数吗?

我的目标是编写一个简单的泛型函数,用于注册任意C ++类型的转换器。为了简单起见,我只打印C ++类型名称。我希望能够print_type_name针对任何类型调用我的泛型函数,包括一次调用多个类型(可变):

template <typename T>
void print_type_name(void)
{
    std::cout << typeid(T).name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

对于以下情况,这可以正常工作:

print_type_name<int>();
print_type_name<std::string>();
print_type_name<std::vector<std::complex<float> > >();
Run Code Online (Sandbox Code Playgroud)

但是,我需要能够为可变参数模板中的每种类型调用此函数,例如(展开时):

print_type_name<int, std::string, std::vector<std::complex<float> > >();
Run Code Online (Sandbox Code Playgroud)

这是我想出的,但是很笨拙:

template <typename ...TS>
void noop(TS... ts) { }

template <typename T>
int real_print_type_name(void) {
    std::cout << typeid(T).name() << std::endl;
    return 0;
}

template <typename ...TS>
void print_type_name(void) {
    noop(real_print_type_name<TS>()...);
}
Run Code Online (Sandbox Code Playgroud)

其中包括以下内容:

template <typename ...TS>
void other_function(void) {
    print_type_name<TS...>();
}
Run Code Online (Sandbox Code Playgroud)

请注意无用的noop函数和的int返回类型 real_print_type_name,为了扩展参数包,我必须添加这两个函数。有没有更干净的方法可以做到这一点?

c++ templates variadic-templates

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