这段代码是否生成真·随机数

2018-01-04 14:12:42 +08:00
 begeekmyfriend

在 OJ 平台上刷题注意到一个现象,有的题用同一份代码,测试 benchmark 落点很稳定,有的在一个时间区间范围内跳跃,不太稳定。用方差描述的话叫做,benchmark 稳定方差小,不稳定方差大。

这就让我突发奇想,能否用一段代码的 benchmark 作为随机数?如果是真·随机数,那么这段代码岂不是可以用来作为随机数生成器了?

如何检验随机性?我考虑可以用 benchmark 落点概率分布来衡量。我设计了一套简陋的代码,其中调用了一些库函数 /系统函数,包括 random、usleep、malloc、free,还有 clock_gettime 用做 benchmark。循环 N 次,统计 benchmark 的所有落点,在终端输出,能够观测概率分布。代码在gist上。翻墙不便的直接贴出来

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

int main(void)
{
        int i, j, k;
        int dim = 11;
        int num = 1024 * 1024;
        int loop = 1000;
        struct timespec start, end;
        size_t stat[200] = { 0 };

        for (k = 0; k < loop; k++) {
                usleep(50000);
                srandom(time(NULL));
                clock_gettime(CLOCK_MONOTONIC, &start);
                for (i = 0; i < num; i++) {
                        double *vector = malloc(dim * sizeof(double));
                        for (j = 0; j < dim; j++) {
                                vector[j] = (double) random() / RAND_MAX * 20 - 10;
                        }
                        free(vector);
                }
                clock_gettime(CLOCK_MONOTONIC, &end);
                size_t rand_ms = (end.tv_sec - start.tv_sec)*1000 + (end.tv_nsec - start.tv_nsec)/1000000;
                stat[rand_ms]++;
        }

        for (i = 0; i < sizeof(stat)/sizeof(*stat); i++) {
                printf("[%d](%f\%):", i, 100.0 * stat[i] / loop);
                for (j = 0; j < stat[i]; j++) {
                        putchar('-');
                }
                putchar('\n');
        }

        return 0;
}

目前循环次数为 1000,运行时间大约 4~5 分钟(机器好可以缩短到 3~4 分钟),我曾经设成 10W 次迭代跑了一个晚上。 原先预想的是,假设系统(或 runtime )稳定的话,benchmark 落点应该近似于正态分布。遗憾的是从终端输出上看,并没有达到随机的效果,但又不是收敛到一个稳定值上,分布比较离散化。

我的几点疑问:

由于仅凭终端输出,这段 C 代码在可视化上有局限,特别当样本量很大的话。Python 好的同学可以试试可视化的库。

4842 次点击
所在节点    程序员
79 条回复
fcten
2018-01-04 15:52:13 +08:00
@begeekmyfriend
我已经说了,benchmark = CPU 运算时间,这是硬件输出的结果。如 17 楼所说,你是把 CPU 作为了噪声发生器。CPU 是一个硬件,不是代码的一部分。
如果你觉得这是纯代码生成的随机数,那么任何程序通过传感器、磁盘 IO 时间、键盘输入、鼠标位置等数据产生随机数也可以认为是纯代码生成的随机数。
eastpiger
2018-01-04 15:54:11 +08:00
楼主确实像炼丹,而不是现代制药

区别在于后者是在现有理论和逻辑学定义基础内的发展和研究,前者是一股脑扔进去看看。

不过也不是说这样没用,毕竟上次炼丹成功的那位,不是发明了火药了嘛:-D

最严格的真随机数生成器,比如对量子态的观测数据,是不可被设计和预测的。(除非楼主打算把量子力学也革命一发了)
begeekmyfriend
2018-01-04 15:54:22 +08:00
@fcten 你见过什么代码不依赖硬件的,把代码送给你,输出给我看?
begeekmyfriend
2018-01-04 15:56:57 +08:00
@eastpiger 我这段代码是基于将近一个世纪计算机科学逻辑理论基础上写就的。
fcten
2018-01-04 15:57:37 +08:00
@begeekmyfriend
你的理解力似乎有一些问题
benchmark 不是代码,而是代码输出的结果,并且这个结果是与硬件有关的
1+1=2,2 是结果,并且这个结果是与硬件无关的
这样你懂了吗
begeekmyfriend
2018-01-04 15:59:53 +08:00
@fcten 你是说没有硬件你只能算 1+1=2 了是吧?我通过对一个计算机编程来生成随机数,本身有问题吗?
fcten
2018-01-04 16:01:42 +08:00
@begeekmyfriend 没问题啊,但是这不是什么大发现,也没有必要在 v2 上发帖
这看上去就好像“我发现太阳每天是从东边升起来的”一样可笑
winglight2016
2018-01-04 16:03:07 +08:00
个人觉得,大家之所以认为微观粒子的量子态是 i.i.d,只是因为量子态就是这么定义的,但是,是不是客观事实(真随机),也没法通过观测证实,换句话说,还是用了数学模型去套的,只是精度很高、吻合得很好,所以,这种随机性如果可以衡量的话,跟 netflix 那个熔岩随机发生器可能差不多
zhx1991
2018-01-04 16:05:21 +08:00
只有量子是真随机
eastpiger
2018-01-04 16:12:26 +08:00
> 我这段代码是基于将近一个世纪计算机科学逻辑理论基础上写就的。

可是你的这个 topic 里的逻辑怕是都过不了一般大学本科的计算理论课程

另外 @winglight2016

真随机数本身是一个数学定义,鉴于其容易证伪却几乎难以证真的特点,另外考虑到理想自然噪声本身也是一种理想化数学定义,并不见得真实存在。所以我们只能探讨的是有多大的可信度相信题主的思路。(但是试图证伪一个广泛接受的其他方案并不影响我们探讨楼主方案是否正确)

讨论问题不可能是没有前提的。我们只能假设前提为依据当前科学主流支持的理论为基础进行,这无可厚非。

至于现在人类科学到底是可信的还是胡扯的,That's not our business.

(当然作为科研工作者的一部分,我们还是倾向于相信它可能有一些是胡扯的。不然后人搞科研都要没饭吃了😂😂)
takato
2018-01-04 16:13:12 +08:00
see:

观测结果上,很多计算机随机出来的东西都是可以被深度学习压缩的。。也就是客观上存在“规律”

所以我个人认为用“巨观物体”其实是不可能做出真随机的。。
SuperMild
2018-01-04 16:13:28 +08:00
@begeekmyfriend 你钻牛角尖了。请看这个函数:

def func(x) ... return y

其中,x 是参数,省略号是纯代码计算过程,y 是结果。假设 y 就是我们讨论的对象:一个随机数。那么,当我们说 y 是一个纯代码产生的不依赖硬件的真随机数时,意思是指 x 不能与硬件、物理世界有关。

当 x 取自硬件或物理世界,只要 x 是真随机的,那我的计算过程只需要 y=x 就可以得出真随机数了,复杂的计算过程只相当于一个放大器,它可以放大随机效果,但它不是随机的源头。
begeekmyfriend
2018-01-04 16:16:37 +08:00
@SuperMild 你的模型想的太狭隘了,def benchmark(code) ... return y,代码难道不能作为数据输入?
SuperMild
2018-01-04 16:29:11 +08:00
@begeekmyfriend 你连 x 是什么也不懂吗? x 可以是任何,当然也可以是代码。

重点是在你的模型中,你输入了一个 “ CPU 运算时间”,这个东西不是纯代码产生的。你依赖了一个硬件的误差。

注意,纯代码无法产生误差,误差是硬件产生的。
begeekmyfriend
2018-01-04 16:32:52 +08:00
@SuperMild 你的意思是纯代码就必须是 immutable 的?这并不成立
SuperMild
2018-01-04 16:35:21 +08:00
@begeekmyfriend 你是怎么联想到 immutable,能不能分享一下心路历程?
winglight2016
2018-01-04 17:26:16 +08:00
@eastpiger 数学定义是没什么问题了,只是既然在讨论程序中的实现哪一个随机性更好,这就不是数学理论一定证明的结论,所以我的观点是,微观粒子的随机性仅仅是数学定义,既没法通过实验证实真随机性,也没法去和熔岩随机数去比较哪一个“更”随机,那么观察熔岩可能是最佳的方案之一了
fyyz
2018-01-04 19:23:50 +08:00
楼主这么倔大家还是不要和他讲道理了吧,我看他也听不进去
Shura
2018-01-04 19:27:46 +08:00
人为不可能实现真随机的,只能通过物理实现。
wecan
2018-01-04 19:37:43 +08:00
楼主真为你捉急

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/420022

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX