C++ “计算”所用时间的最佳方法是什么;在c+中复制二进制文件+;在linux上;?
我使用以下代码复制大小约为1.1GB的文件C++ “计算”所用时间的最佳方法是什么;在c+中复制二进制文件+;在linux上;?,c++,linux,C++,Linux,我使用以下代码复制大小约为1.1GB的文件 #include <iostream> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <sys/sendfile.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include &l
#include <iostream>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctime>
using namespace std;
int main ()
{
clock_t start, end;
start = clock();
int read_fd;
int write_fd;
struct stat stat_buf;
off_t offset = 0;
/* Open the input file. */
read_fd = open ("source", O_RDONLY);
/* Stat the input file to obtain its size. */
fstat (read_fd, &stat_buf);
/* Open the output file for writing, with the same permissions as the
source file. */
write_fd = open ("destination", O_WRONLY | O_CREAT, stat_buf.st_mode);
/* Blast the bytes from one file to the other. */
sendfile (write_fd, read_fd, &offset, stat_buf.st_size);
/* Close up. */
close (read_fd);
close (write_fd);
end = clock();
cout << "CLOCKS_PER_SEC " << CLOCKS_PER_SEC << "\n";
cout << "CPU-TIME START " << start << "\n";
cout << "CPU-TIME END " << end << "\n";
cout << "CPU-TIME END - START " << end - start << "\n";
cout << "TIME(SEC) " << static_cast<double>(end - start) / CLOCKS_PER_SEC << "\n";
return 0;
}
但是,当我实际计算时间时,它(复制)大约需要84秒!!!
现在我将在下面的代码中使用“structure timeval”,输出结果是:83 456677
,它与实际时间几乎相同
#include <iostream>
#include <sys/sendfile.h> // sendfile
#include <fcntl.h> // open
#include <unistd.h> // close
#include <sys/stat.h> // fstat
#include <sys/types.h> // fstat
#include <ctime>
extern "C" {
#include <sys/time.h>
}
#include <stdio.h>
using namespace std;
int main() {
struct timeval diff, startTV, endTV;
gettimeofday(&startTV, NULL);
int source = open("source", O_RDONLY, 0);
int dest = open("distination", O_WRONLY | O_CREAT /*| O_TRUNC/*/, 0644);
// struct required, rationale: function stat() exists also
struct stat stat_source;
fstat(source, &stat_source);
sendfile(dest, source, 0, stat_source.st_size);
close(source);
close(dest);
gettimeofday(&endTV, NULL);
timersub(&endTV, &startTV, &diff);
printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);
return 0;
}
#包括
#包含//发送文件
#包含//打开
#包括//关闭
#包括//fstat
#包括//fstat
#包括
外部“C”{
#包括
}
#包括
使用名称空间std;
int main(){
结构timeval diff、startTV、endTV;
gettimeofday(&startTV,NULL);
int source=open(“source”,orduonly,0);
int dest=open(“区分”,O|u WRONLY | O|u CREAT/*| O|u TRUNC/*/,0644);
//结构必需,理由:函数stat()也存在
结构统计源;
fstat(源和统计源);
sendfile(dest,source,0,stat\u source.st\u size);
关闭(源);
关闭(dest);
gettimeofday(&endTV,NULL);
timersub(&endTV,&startTV,&diff);
printf(“**所用时间=%ld%ld\n”,diff.tv\u秒,diff.tv\u usec);
返回0;
}
然后我将使用“pv source>destination”命令,然后输出为:1.02e+03MB 0:01:24[12.1MB/s][=================================>]100%
,与实际时间相同
#include <iostream>
#include <sys/sendfile.h> // sendfile
#include <fcntl.h> // open
#include <unistd.h> // close
#include <sys/stat.h> // fstat
#include <sys/types.h> // fstat
#include <ctime>
extern "C" {
#include <sys/time.h>
}
#include <stdio.h>
using namespace std;
int main() {
struct timeval diff, startTV, endTV;
gettimeofday(&startTV, NULL);
int source = open("source", O_RDONLY, 0);
int dest = open("distination", O_WRONLY | O_CREAT /*| O_TRUNC/*/, 0644);
// struct required, rationale: function stat() exists also
struct stat stat_source;
fstat(source, &stat_source);
sendfile(dest, source, 0, stat_source.st_size);
close(source);
close(dest);
gettimeofday(&endTV, NULL);
timersub(&endTV, &startTV, &diff);
printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);
return 0;
}
而且,当我以图形模式复制文件时(复制/粘贴普通模式),大约需要84秒
问题
这不是对你问题的直接回答,但你可能会发现非常有用,除非你绝对需要在你的程序中存储统计数据 测试
$ cat /dev/urandom > chunk.bin
^C
$ strace -T cp -p chunk.bin dust.bin
输出(请参见每个系统调用后三角括号中的数字)
stat(“dust.bin”,0x7fff747c5640)=-1 enoint(没有这样的文件或目录)
stat(“chunk.bin”,{st_mode=S_IFREG | 0664,st_size=19202048,…})=0
stat(“dust.bin”,0x7fff747c5290)=-1 enoint(没有这样的文件或目录)
打开(“chunk.bin”,O_RDONLY)=3
fstat(3,{st_mode=S_IFREG | 0664,st_size=19202048,…})=0
打开(“灰尘箱”,O|u WRONLY | O|u CREAT | O|u EXCL,0600)=4
fstat(4,{st_mode=S_IFREG | 0600,st_size=0,…})=0
读(3),“\216\330A\27J\373\1a\10\262&\221B\255\271\227\342:\252?\334\3169a\212\27\205=+\300\273\370”…,32768)=32768
写(4),“\216\330A\27J\373\1a\10\262&\221B\255\271\227\342:\252?\334\3169a\212\27\205=+\300\273\370”…,32768)=32768
读(3),“\327\344\343 |\243\247\211\200\211\212\331\247WF\324\33\276\317\241[{\24\354D\223\215\332\247\34\376\246W”…,32768)=32768
写(4),“\327\344\343 |\243\247\211\200\211\212\331\247WF\324\33\276\317\241[{\24\354D\223\215\332\247\34\376\246W”…,32768)=32768
...
读(3,“,32768)=0
utimensat(4,NULL,{1392157379551634340},{1392157405,783308564},0)=0
fgetxattr(3,“system.posix_acl_access”,0x7fff747c4f50132)=-1 ENODATA(无可用数据)
fstat(3,{st_mode=S_IFREG | 0664,st_size=19202048,…})=0
fsetxattr(4,“system.posix_acl_access”,“\x02\x00\x00\x00\x01\x00\x06\x00\xff\xff\xff\xff\x04\x00\x06\x00\xff\xff\xff\xff\x04\x00\xff\xff\xff”,28,0)=0
关闭(4)=0
关闭(3)=0
第一种方式计算的时间是多少
它是程序使用CPU所花费的时间。clock()测量CPU时间。复制文件
通常,大部分时间都花在做其他事情上(I/O,例如等待硬盘移动或响应,等待内核中的锁,等等)
“pv”或“Pipe Viewer”是否正确显示操作系统“复制文件所花费的时间”
它显示从接收第一个字节到接收最后一个字节所用的时间
请记住,写入文件通常只会写入文件系统缓存,因此它只是写入RAM。操作系统会在空闲时将缓存刷新到驱动器,这可能是在您的程序、cp
程序或您使用的任何GUI文件管理器宣布复制完成之后。(这不是真正的问题,除非您切断电源,从您复制到的文件中读取内容将通过相同的缓存)
如果要确保将数据刷新到驱动器,请调用文件描述符上的()
这也意味着您可以轻松测量复制文件的不同时间。如果文件或其部分恰好位于文件系统缓存中,则您正在从RAM中读取。如果文件不在缓存中,则需要从驱动器中读取,速度可能会慢一到两个数量级
我们是否得出结论,sendfile()用于复制的时间与OS几乎相同
对不起,我不知道你在这里问什么…..很多人在这个网站上查看/阅读标签。我把你的C++标签改成C.@ CastAutiReFue。他使用的是代码> IoSturi和
cp
相同,那么肯定是的。
stat("dust.bin", 0x7fff747c5640) = -1 ENOENT (No such file or directory) <0.000303>
stat("chunk.bin", {st_mode=S_IFREG|0664, st_size=19202048, ...}) = 0 <0.000341>
stat("dust.bin", 0x7fff747c5290) = -1 ENOENT (No such file or directory) <0.000281>
open("chunk.bin", O_RDONLY) = 3 <0.000272>
fstat(3, {st_mode=S_IFREG|0664, st_size=19202048, ...}) = 0 <0.000272>
open("dust.bin", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4 <0.000404>
fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 <0.000272>
read(3, "\216\330A\27J\373\1a\10\262&\221B\255\271\227\342:\252?\334\3169a\212\27\205=+\300\273\370"..., 32768) = 32768 <0.000684>
write(4, "\216\330A\27J\373\1a\10\262&\221B\255\271\227\342:\252?\334\3169a\212\27\205=+\300\273\370"..., 32768) = 32768 <0.000359>
read(3, "\327\344\343|\243\247\211\200\211\212\331\247WF\324\33\276\317\241[{\24\354D\223\215\332\247\34\376\246W"..., 32768) = 32768 <0.000494>
write(4, "\327\344\343|\243\247\211\200\211\212\331\247WF\324\33\276\317\241[{\24\354D\223\215\332\247\34\376\246W"..., 32768) = 32768 <0.000379>
...
read(3, "", 32768) = 0 <0.000226>
utimensat(4, NULL, {{1392157379, 551638340}, {1392157405, 783308564}}, 0) = 0 <0.000254>
fgetxattr(3, "system.posix_acl_access", 0x7fff747c4f50, 132) = -1 ENODATA (No data available) <0.000234>
fstat(3, {st_mode=S_IFREG|0664, st_size=19202048, ...}) = 0 <0.000223>
fsetxattr(4, "system.posix_acl_access", "\x02\x00\x00\x00\x01\x00\x06\x00\xff\xff\xff\xff\x04\x00\x06\x00\xff\xff\xff\xff \x00\x04\x00\xff\xff\xff\xff", 28, 0) = 0 <0.000285>
close(4) = 0 <0.000250>
close(3) = 0 <0.000267>