GVKun编程网logo

实现基于整数的幂函数pow(int,int)的最有效方法(oj整数幂)

24

本文将为您提供关于实现基于整数的幂函数pow的详细介绍,我们还将为您解释int,int的最有效方法的相关知识,同时,我们还将为您提供关于1.函数sum(inta[],intn)的返回值是数组a[]的前

本文将为您提供关于实现基于整数的幂函数pow的详细介绍,我们还将为您解释int,int的最有效方法的相关知识,同时,我们还将为您提供关于1. 函数sum(int a [],int n)的返回值是数组a[]的前几个元素之和。 请使用...、assembly – 将uint32的向量转换为float向量的最有效方法?、c – 在一系列公共基类型中获取整数类型id的最有效方法、c# – 扫描Windows进程列表的最有效方法?的实用信息。

本文目录一览:

实现基于整数的幂函数pow(int,int)的最有效方法(oj整数幂)

实现基于整数的幂函数pow(int,int)的最有效方法(oj整数幂)

将整数提升为C中另一个整数的幂的最有效方法是什么?

// 2^3pow(2,3) == 8// 5^5pow(5,5) == 3125

答案1

小编典典

通过平方求幂。

int ipow(int base, int exp){    int result = 1;    for (;;)    {        if (exp & 1)            result *= base;        exp >>= 1;        if (!exp)            break;        base *= base;    }    return result;}

这是对不对称密码中的大量数字进行模幂运算的标准方法。

1. 函数sum(int a [],int n)的返回值是数组a[]的前几个元素之和。 请使用...

1. 函数sum(int a [],int n)的返回值是数组a[]的前几个元素之和。 请使用...

#include<stdlib.h>
#include<stdio.h>
#define N 10
int sum1(int *list,int n)
{
    int i ;
    int ret = 0 ;
    for(i = 0 ; i<n;++i)
       ret += list[i];

    return ret ;
}

int sum2(int * list, int n)
{

    if (n>1) 
        return list[n-1]+sum2(list,n-1);
    else 
        return list[0];
}
int sum3(int *list , int n)
{
    if(n==1)
        return list[0];
    else 
        return list[n-1]+sum3(list,n-1);
}
int main()
{
    int i ;
    int list[N];
    for (i=0  ; i<N ;++i ) {
        list[i]= i+1;
    }
    int ret1 ;
    int ret2 ;
    ret1 = sum1(list,N);
ret2 = sum2(list,N);
int ret3 = sum3(list,N);

    printf("%d\t%d\t%d\n",ret1,ret2,ret3);
    return 0 ;
}

gcc -g -o sum sum.c 

assembly – 将uint32的向量转换为float向量的最有效方法?

assembly – 将uint32的向量转换为float向量的最有效方法?

x86没有从无符号int32转换为浮点的SSE指令.实现这一目标的最有效指令序列是什么?

编辑:
为了澄清,我想做以下标量操作的向量序列:

unsigned int x = ...
float res = (float)x;

EDIT2:这是一个用于进行标量转换的简单算法.

unsigned int x = ...
float bias = 0.f;
if (x > 0x7fffffff) {
    bias = (float)0x80000000;
    x -= 0x80000000;
}
res = signed_convert(x) + bias;

解决方法

您的天真标量算法无法提供正确的舍入转换 – 它会在某些输入上遭受双舍入.举个例子:如果x是0x88000081,那么转换为float的正确舍入结果是2281701632.0f,但是你的标量算法将返回2281701376.0f.

在我的头顶,你可以做如下正确的转换(正如我所说,这是我的头顶,所以它可能在某处保存指令):

movdqa   xmm1,xmm0    // make a copy of x
psrld    xmm0,16      // high 16 bits of x
pand     xmm1,[mask]   // low 16 bits of x
orps     xmm0,[onep39] // float(2^39 + high 16 bits of x)
cvtdq2ps xmm1,xmm1     // float(low 16 bits of x)
subps    xmm0,[onep39] // float(high 16 bits of x)
addps    xmm0,xmm1    // float(x)

常量具有以下值:

mask:   0000ffff 0000ffff 0000ffff 0000ffff
onep39: 53000000 53000000 53000000 53000000

这样做是将每个通道的高半部分和低半部分分别转换为浮点数,然后将这些转换后的值相加.因为每一半只有16位宽,所以转换为float不会产生任何舍入.仅在添加两半时才进行舍入;因为加法是一个正确舍入的操作,所以整个转换都是正确舍入的.

相比之下,你的天真实现首先将低31位转换为浮点数,这会导致舍入,然后有条件地将2 ^ 31加到该结果,这可能会导致第二次舍入.每当你在转换中有两个单独的舍入点时,除非你非常小心它们是如何发生的,否则你不应该期望结果被正确舍入.

c – 在一系列公共基类型中获取整数类型id的最有效方法

c – 在一系列公共基类型中获取整数类型id的最有效方法

问题:

我有一个具有共同基础的对象族,我需要能够通过整数值来识别特定的具体类型.

有两种明显的方法可以做到这一点,但是在内存或cpu时间方面都会产生不可接受的开销.由于该项目涉及数十亿个对象,因此最微小的开销最终会发出严重的声音,而且我已经对此进行了测试,这不是过早优化的情况.处理对象所涉及的操作都是微不足道的,虚拟调用的开销极大地降低了性能.

>为每种类型实现的纯虚拟int类型()函数,不幸的是,它带来了虚拟调用的开销,这对于返回静态整数值一样微不足道
>构造函数类型中指定的每个实例的int类型成员,它为这些数十亿个对象中的每一个引入了4字节开销,浪费内存,污染缓存等等

我记得前段时间有人询问“静态虚拟成员变量”,自然答案归结为“不,这没有意义”,但是能够将用户变量放在vtable中并且能够设置其值对于每个特定类型似乎是一个非常有效的解决我的问题.

这样就避免了上述两种开销,不需要虚拟调用,也没有每个实例的内存开销.唯一的开销是获取vtable的间接,但考虑到访问该数据的频率,它很可能大部分时间都保存在cpu缓存中.

我目前显而易见的选择是做“手动OOP” – 手动执行vtables以便将必要的“元”数据合并到它们中,为每种类型初始化vtable指针并使用笨拙的语法来调用伪“成员”函数.或者甚至完全省略vtable指针的使用,而是存储id,并将其用作vtable表的索引,这将更有效,因为它将避免间接,并将缩小大小,因为我只需要2 ^ 14种不同的类型.

如果我能避免重新发明轮子那就太好了.只要能给我效率保证,我对解决方案并不挑剔.

也许有一种方法可以在vtable中使用我的类型id整数,或者可能还有另一种方式,这很可能因为我跟不上趋势,而C在最后几个中获得了很多新功能年份.

当然,那些id需要统一和一致,而不是编译器内部编写的任何值.如果这不是一个要求,我只是使用vtable指针值来获得更有效的解决方案,避免间接.

有任何想法吗?

解决方法

如果你有更多的实例而不是类型,那么最直接的解决方案是在同类容器而不是单个实例的层次上进行抽象.

代替:

{polymorphicContainer}: Foo*,Bar*,Baz*,Foo*,...

…并且必须存储一些类型信息(vtable,类型字段等)以区分每个元素,同时以最零星的方式访问内存,您可以:

{FooContainer}: Foo,Foo,...
{BarContainer}: Bar,Bar,...
{BazContainer}: Baz,Baz,...
{polymorphicContainer}: FooContainer*,BarContainer*,BazContainer*

并且您将容器内的类型信息(vtable或不是)存储起来.这确实意味着你需要一种更加同质的访问模式,但通常这种安排可以在我遇到的大多数问题中进行.

Gamedevs过去常常按照子类型对多态基本指针进行排序,同时使用自定义分配器为每个按钮连续存储它们.通过基指针地址排序和从不同的池中分配每种类型的组合使得您可以获得类似的等效:

Foo*,...,...

其中大多数都是连续存储的,因为它们各自使用一个自定义分配器,它将所有Foos放入与所有条形分开的连续块中,例如,然后,在空间局部性的顶部,如果以连续模式访问事物,则还可以在vtable上获得时间局部性.

但是这对我来说比在容器级别抽象更痛苦,并且这样做仍然需要每个对象的两个指针(64位机器上128位)的开销(vptr和指向对象本身的基指针) ).不是通过Creature * base指针单独处理orcs,goblins,human等,我将它们存储在同类容器中,抽象出来,并处理指向整个同类集合的Creatures *指针是有意义的.代替:

class Orc: public Creature {...};

… 我们的确是:

// vptr only stored once for all orcs in the entire game.
class Orcs: public Creatures
{
public:
    // public interface consists predominantly of functions
    // which process entire ranges of orcs at once (virtual
    // dispatch only paid once possibly for a million orcs
    // rather than a million times over per orc).
    ...

private:
    struct OrcData {...};
    std::vector<OrcData> orcs;
};

代替:

for each creature:
     creature.do_something();

我们的确是:

for each creatures:
     creatures.do_something();

使用这种策略,如果我们在视频游戏中需要一百万个兽人,我们会将与虚拟调度,vptrs和基本指针相关的成本降低到原始成本的1 / 1,000,更不用说你得到的最佳位置了参考也是免费的.

如果在某些情况下我们需要对特定生物做某事,你可能能够存储一个两部分索引(可能能够适合32位或48个)存储生物类型索引,然后存储相对生物指数那个容器,虽然这个策略最有用,当你不必调用函数来处理关键路径中的一个生物时.通常,您可以将此值设置为32位索引或者可能是48位,如果您在每个同类容器设置为2 ^ 16之前设置其限制,然后再将其视为“已满”,并为同一类型创建另一个容器,例如如果我们想要填充索引,我们不必将一种类型的所有生物存储在一个容器中.

我不能确定这是否适用于您的情况,因为它取决于访问模式,但它通常是我遇到与多态性相关的性能问题时考虑的第一个解决方案.我看待它的第一种方式是你付出的代价是虚拟调度,连续访问模式的丢失,vtable上时间局部性的丢失,vptr的内存开销等等.使设计更粗糙(更大的对象,如代表整个事物集合的对象,而不是每个事物的单个对象),成本再次可以忽略不计.

无论情况如何,而不是在vtable方面考虑这个问题,而不是考虑如何排列数据,只考虑位和字节,这样你就不必每次都存储一个指针或整数.单个小物件.只考虑位和字节,而不是类和vtable和虚函数以及漂亮的公共接口等等.在确定内存表示/布局之后再考虑一下,然后开始考虑位和字节,如下所示:

我发现这对于面向数据的设计来说更容易思考,而不是试图考虑语言机制和漂亮的界面设计以及所有这些,这些设计具有令人期待的性能关键需求.相反,我认为首先是以类似于C的方式使用位和字节,并将我的想法作为结构进行通信和绘制,并找出位和字节的位置.然后,一旦你想出来,你就可以弄清楚如何在顶部放置一个漂亮的界面.

无论如何,为了避免每个青少年对象的类型信息的开销,这意味着它们以某种方式在内存中组合在一起并且每组存储该类比类型字段而不是每组中的元素存储一次.以统一的方式分配特定类型的元素也可能会根据指针地址或索引为您提供信息,例如:有很多方法可以解决这个问题,但只需考虑存储在内存中的数据作为一般策略.

答案有点嵌入您的问题主题:

Most efficient way to get an integer type id in a family of common
base types […]

您可以为每个族存储一次整数ID,或者为该族中的每个多个对象存储至少一次,而不是每个对象存储一次.这是唯一的方法,无论你接近它,避免每个对象存储一次,除非信息已经可用.另一种方法是从其他一些可用的信息中推断出它,就像你可以从对象的索引或指针地址中推断它一样,此时存储ID只是冗余信息.

c# – 扫描Windows进程列表的最有效方法?

c# – 扫描Windows进程列表的最有效方法?

所以我目前正在开发一个项目,需要在某些进程运行时需要时间.我正在尝试找出扫描进程列表的最有效方法,然后根据支持的程序列表检查进程列表可执行文件名称.

基本上问题是两部分:

1)从进程列表中获取进程可执行文件名称的最有效方法

2)将此列表与另一个列表进行比较的最有效方法

对于(1),其他开发人员之一正在使用tasklist命令并解析出可执行文件名称.我还发现C#有一个System.Diagnostic进程列表,它将自动执行此操作.我们仍在尝试在Java和C#之间做出决定,所以我可能倾向于使用语言中立的解决方案,但这可能是C#的决定性因素.

对于(2),支持的进程列表平均可能很小(1-10个进程名称).我们可以通过列表运行每个进程,但是我们认为这对于旧PC来说可能太多了,所以我们在使用包含应用程序启动时的初始进程列表的字母平衡的AVL树并且检查所有内容的想法首先反对,然后检查我们支持的进程名称列表,如果它不在树中.

任何建议都非常感谢.

编辑:显然,您可以按进程可执行文件名筛选任务列表,因此我们可以对支持的进程列表中的每个进程执行此操作.

编辑2:是否有适用于Windows XP Home的任务列表等效?

解决方法

如果你使用任务列表,实际上运行命令一次并获取所有结果实际上会更快,而不是为每个可执行文件名运行它.执行进程和获取输出有一些开销. (当你返回结果时,你将不得不在代码中循环它们,但这可能会更快.通常一次运行的进程不会超过100个,所以它不会太糟糕.)你应该写一个测试并检查是否真的.

在C#中,Process.GetProcesses()是最好的方法.

在Java中,并没有真正的等价类/方法.获取进程列表非常特定于操作系统,因此Java设计人员必须决定不将此功能集成/抽象到基本java类中.您可能需要Runtime.getRuntime().exec(“tasklist.exe”)才能在Windows上获得结果,或者在Unix / Linux上获得exec(“ps”).

今天关于实现基于整数的幂函数powint,int的最有效方法的讲解已经结束,谢谢您的阅读,如果想了解更多关于1. 函数sum(int a [],int n)的返回值是数组a[]的前几个元素之和。 请使用...、assembly – 将uint32的向量转换为float向量的最有效方法?、c – 在一系列公共基类型中获取整数类型id的最有效方法、c# – 扫描Windows进程列表的最有效方法?的相关知识,请在本站搜索。

本文标签: