首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我写的不能超过2GB?

为什么我写的不能超过2GB?
EN

Stack Overflow用户
提问于 2021-04-01 07:46:50
回答 2查看 279关注 0票数 0

我正在使用这段代码来测量我的计算机的写入带宽。程序需要两个参数,我们将要写入的文件的名称和MB的数量。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/time.h>


int main(int argc, char *argv[]) {
    struct timeval tv0, tv1;
    int chunkSize = 128, res;
    char str[chunkSize];
    
    if (argc != 3)
    perror("Usage: file_name Mb.");
     
    int megabytes = atoi(argv[2]);
    int sizeWrite = megabytes*1024*1024;
    int sizeWriteAux = sizeWrite;

    FILE * fp;
    fp = fopen (argv[1], "w+");

    res = gettimeofday(&tv0, NULL);
    if (res < 0) {
         perror ("gettimeofday");
    }
    
    while (sizeWriteAux > 0) {
     fwrite(str , 1 , chunkSize , fp );
        sizeWriteAux -= chunkSize;
    }
    
    res = gettimeofday(&tv1, NULL);
    if (res < 0) {
         perror ("gettimeofday");
    }
    
    fclose(fp);
    
    double secs = (((double)tv1.tv_sec*1000000.0 + (double)tv1.tv_usec) - ((double)tv0.tv_sec*1000000.0 + (double)tv0.tv_usec))/1000000.0;
    printf("Time: %f \n", secs);
    
    double x = sizeWrite/secs;
    double y = megabytes/secs;
    printf("Bandwith: %f bytes x sec \n", x);
    printf("Bandwith: %f Mbytes x sec \n", y);

    return(0);
}

该程序可以正常工作到2047 MB,但到2048年它不写任何东西,并且不返回任何错误而导致无限带宽。

我在VirtualBox的Ubuntu 20上运行这个程序,内存为12 GB,空闲磁盘内存为10 GB。

有人知道为什么会这样吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-01 08:19:09

代码语言:javascript
复制
int megabytes = atoi(argv[2]);
int sizeWrite = megabytes*1024*1024;
int sizeWriteAux = sizeWrite;

你在使用int。似乎,在您的系统sizeof(int) == 4 (bytes)上。因为intsigned,而1位是符号,所以只能使用31位。

2^31 = 2147483648 (2G)

如果您使用的是unsigned int,那么

2^32 = 4294967296 (4G)

有什么不同,对吧?

现在想象一下,您将使用(long) long int,即64位。

您应该小心底层文件系统文件大小的限制。例如,Fat文件的上限为最大2G。

票数 1
EN

Stack Overflow用户

发布于 2021-04-01 08:17:21

带宽xy分别是-inf和inf,因为sizeWrite是正的,megabytes是负的,secs是接近0的。兆字节是负的,因为sizeWrite = megabytes*1024*1024中的溢出值大于2^31 -1(Int) == 4。secs接近0,因为sizeWriteAux是负的,因为它被初始化为megabytes,这意味着than循环根本不运行。第一步的修正是:

代码语言:javascript
复制
unsigned long sizeWrite = megabytes*1024*1024;
unsigned long sizeWriteAux = sizeWrite;

如果未指定两个参数,则程序将崩溃。一般情况下,您缺少错误检查。(2):

通常情况下,文件系统在文件关闭时不会刷新缓冲区。如果需要确保数据物理地存储在底层磁盘上,请使用fsync(2)。

您还需要对secs进行检查,以确保它足够大,从而避免xy溢出。当值为正时使用无符号类型。

你可能会对此感兴趣:

代码语言:javascript
复制
file=...
size=...
block_size=128
time dd if=/dev/zero of=$file bs=$block_size count=$(($size * 1024 * 1024 / $block_size))

在n至少为1的block_size = 4096 * n中,您可能会看到性能的提高。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66900374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档