小编Fra*_*ffa的帖子

n是负数,正数还是零?返回1,2或4

我正在构建一个PowerPC解释器,它运行得很好.在Power架构中,条件寄存器CR0(x86上的EFLAGS)几乎在任何指令上都会更新.它是这样设置的.如果最后一个结果为负,则CR0的值为1,如果最后结果为正,则为2,否则为4.

我的第一个天真的解释方法是:

if (n < 0)
    cr0 = 1
else if (n > 0)
    cr0 = 2;
else
    cr0 = 4;
Run Code Online (Sandbox Code Playgroud)

但是我知道所有这些分支都不是最佳的,每秒运行数百万次.我已经看到了一些有点黑客攻击,但似乎没有任何东西.例如,我发现许多例子将数字转换为-1,0或1,相应地符号为0.但是如何使-1 = 1,1 = 2 = 0?我要求Bit Hackers的帮助......

提前致谢

更新: 首先:谢谢你们,你们一直很棒.我会仔细测试你的所有代码以获得速度,你将成为第一个知道谁是胜利者的代码.

@jalf:关于你的第一个建议,我实际上并没有在每条指令上计算CR0.我宁愿保留一个lastResult变量,当(和如果)以下指令要求标志时,进行比较.三个主要动机让我回到"每次"更新:

  1. 在PPC上,您不必像在x86上那样更新CR0(其中ADD总是更改EFLAGS,即使不需要),您有两种ADD,一种更新.如果编译器选择使用更新版本,则意味着它将在某个时刻使用CR0,因此没有必要延迟...
  2. 有一个特别痛苦的指令叫做mtcrf,它可以让你随意改变CR0.你甚至可以把它设置为7,没有算术意义......这只会破坏保留"lastResult"变量的可能性.

c++ bit-manipulation bit-shift bit

35
推荐指数
3
解决办法
1967
查看次数

是否可以将汇编语言转换为LLVM IR,对其进行优化,然后将其重新编译为不同的架构?

是否可以将汇编语言转换为LLVM IR,对其进行优化,然后将其重新编译为不同的架构?如何在IR中处理堆栈中的"推送"和"弹出"?这是我发现的最简单的反对意见,但我确信有这么多的反对意见.

我打算构建一个动态重新编译器,看起来这将是一个很好的解决方案,因为LLVM会自动优化我的新架构代码.LLVM是否可以实现这一切?

谢谢

assembly llvm recompile

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

如何编写好的软件而不会卡住

我已经在我的个人项目上工作多年了,这是一个从零开始制作的操作系统.你可能认为它是相当复杂的东西.问题是我多次从头开始工作.这意味着在某些时候(非常先进,我有硬盘读/写和一些基本的网络),事情太混乱了,我决定把它扔到窗口再试一次.多年来,我学会了如何使代码看起来更好,我读了罗伯特·马丁的"清洁代码 - 敏捷软件工艺手册",它帮助了很多.我学会了使函数变小,在类中组织事物(我使用C,现在是C++)和命名空间,使用异常和测试进行适当的错误处理.然而,这种新方法让我陷入困境,我花了大部分时间来检查一切进展顺利,代码读得好,这很容易,评论和测试都很好.基本上我几个月没有做任何相关的步骤.当我看到编写良好的代码时,很难添加新的功能并想"我应该把它放在哪里?我已经使用过这段代码吗?最好的方法是什么?" 我经常推迟工作.

所以,这就是问题所在.您是否知道任何代码编写策略,使您编写工作,测试,良好的代码,而不花费90%的时间来思考如何使其工作,测试和良好?

提前致谢.

c++ agile

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

具有O(1)Dequeue和O(无论)入队的优先级队列

我正在用C++编写一个应用程序,其中对优先级队列进行O(1)Dequeue操作至关重要,而Enqueue的复杂性并不是那么重要(当然,除非它变成n ^ 2或2 ^ n).

起初我使用了一个链表.这对Dequeue(O(1))来说非常好,并且它具有良好的入队复杂性.唯一的问题是,整理它.使用Insertion Sort,O(n)复杂度并不符合我的需求.但排序链表很麻烦.这是懒散的.

矢量并不好.Dequeue将是O(n)将所有元素移回一个地方.入队仍然是O(n)但速度要快得多.

你能建议更高效的方法吗?谢谢.

c++ algorithm priority-queue

5
推荐指数
2
解决办法
3477
查看次数

使用 Xlib 启用抗锯齿

我正在尝试开发一组自定义库,用于在 Linux 中创建 GUI,其中包括小部件、按钮等。所以我现在正在学习使用X11及其Xlib创建用户界面。我得到了一个漂亮的窗口,它具有指定的大小、指定的位置、指定的背景颜色,并且可以绘制点、矩形、圆弧。然而,当我绘制第一个圆圈时,我对圆圈没有抗锯齿这一事实感到非常失望。我可以将每个像素视为一个正方形。

现在问题很简单了。有什么办法告诉X:请在绘制之前进行抗锯齿处理吗?或者我是否必须避免使用 XDrawArc 并使用为圆的每个点调用 XDrawPoint 的自定义函数?或者还有第三种解决方案?

提前致谢。

x11 drawing antialiasing xlib

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

如何创建类类型数组?

我有一个单独的"Base"类,以及从Base派生的几十个类.我想有一个方法,通过索引创建正确的类.像这样:

class Base
{
};

class A : public Base
{
}

class B : public Base
{
}

class C : public Base
{
}

Type array = { A, B, C };
Run Code Online (Sandbox Code Playgroud)

然后我就能做到 new array[i];

如何用C++(0x)实现这一目标?通常我会使用抽象工厂模式.但是由于我有很多派生类,这确实会减慢程序的速度.

由于派生类只会使用一次我也教过使用它:

Base *array = { new A, new B, new C };
Run Code Online (Sandbox Code Playgroud)

但是这会导致巨大的内存消耗,不计算并不是每个类都会被使用.

有什么建议吗?

c++ arrays types abstract-factory

4
推荐指数
2
解决办法
1万
查看次数

OpenSSL让服务器和客户端协商该方法

在一个非常过时的教程之后,我设法使用OpenSSL和TLS1.2创建了一个HTTPS服务器,我为此感到非常自豪;)

但是TLS 1.2仅在最新的浏览器中得到支持,我想在客户端和服务器之间进行某种协议的协商,我确信它可以完成,但是我无法找到它!因此,如果客户端仅支持TLS1.0,那么请使用它.如果它只支持SSLv3,请使用它.不确定SSLv2,也许最好离开......

我现在使用的代码是:

SSL_library_init();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ssl_method = TLSv1_2_server_method();
ssl_ctx = SSL_CTX_new(ssl_method);
Run Code Online (Sandbox Code Playgroud)

然后加载服务器证书,并ssl_ctx在所有连接之间共享.当客户accept端由服务器套接字编辑时,它被封装在SSL对象中(无论它代表什么):

ssl = SSL_new(ssl_ctx);
SSL_set_fd(ssl, client_socket);
SSL_accept(ssl);
Run Code Online (Sandbox Code Playgroud)

所以我想在ssl_ctx创建中必须更改某些内容以允许更多方法...任何想法?

<rant> OpenSSL没有相当广泛的文档,最好的是10年的教程!</咆哮>

提前致谢.

ssl openssl

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

具有非指针/引用返回类型的协变返回类型

我正在尝试在C++(11)中实现类似集合类的.NET框架.我的问题是无效的协变类型.我有这些课程:

template<typename T>
class IEnumerator
{
public:
    virtual bool MoveNext() = 0;
    //...
};

template<typename T>
class IEnumerable
{
    virtual IEnumerator<T> GetEnumerator() = 0;
};

template<typename T>
class List : public IEnumerable<T>
{
public:
    struct Enumerator : public IEnumerator<T>
    {
        Enumerator(List<T> &list)
        {
            //...
        }
        // ...
    };

    Enumerator GetEnumerator()
    {
        return Enumerator(*this);
    }
};
Run Code Online (Sandbox Code Playgroud)

据我说,这太棒了.但在C++中实现它似乎是不可能的.我得到了g ++的"无效协变返回类型",据我所知,问题是GetEnumerator可能只返回一个指针或对Enumerator的引用,而不是Enumerator本身的对象.

我想避免返回这样的指针:

Enumerator *GetEnumerator()
{
    return new Enumerator(*this);
}
Run Code Online (Sandbox Code Playgroud)

因为我不希望调用者打扰删除.使用临时对象我确定该对象会被自动删除,因为它不再需要了.使用引用可能更糟糕.

我错过了什么吗?或者C++标准(和语言)中是否存在巨大漏洞?我真的很想实现这样的目标.

提前致谢.

c++ ienumerable pointers return-type covariant

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

两个数组下标重载读写

我想要一个带有两个数组下标运算符重载的类:一个用于读取,另一个用于写入。

倾诉是保持变化的计数器。我读到(在http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node97.html)我可以做这样的事情:

template<typename T>
class Array
{
public:
    Array()
    {
        data = new T[100];
    }

    T &operator[] (int index)
    {
        cout << "Is writing\n";
        changes++;
        return data[index];
    }

    T operator[] (int index) const
    {
        cout << "Is reading\n";
        return data[index];
    }

private:
    T *data;
    int changes;
};
Run Code Online (Sandbox Code Playgroud)

但这在我的情况下不起作用。我正在使用带有 -std=c++11 的 g++ 4.7 并且实际上只有“正在写入”打印在屏幕上,即使我这样做:

Array<int> a;
a[0] = 3;
cout << a[0] << endl;
Run Code Online (Sandbox Code Playgroud)

我还注意到后者永远不会通过使用 gcov 检查源代码来调用。该页面上的方法是完全错误的,还是我误解了?

提前致谢。

c++ arrays setter class operator-overloading

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