- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我目前正在测试在两个 Fortran 程序之间有效传递数据的不同方法。我试过写入文件、管道和 TCP/IP。我的测试结果如下所示。请注意,图表仅显示 4*10^4 B 的时间,因为这是我为文件和管道设置的高度。 4*10^6 B测试只针对TCP/IP程序进行。
为了测试执行时间,我使用了大多数 Linux 发行版中的 time
程序,即:time ./program
。然后我使用 real
值作为我的时间。
很明显,写入文件和使用管道是线性的。有一些开销,但它非常简单。然而,TCP/IP 协议(protocol)似乎不受影响 - 无论数据量如何。
实际发生的是:
可以在下面的 4 个不同程序中看到执行此操作的代码。令我感到困惑的是,该程序的 TCP/IP 版本似乎不受数据量的影响。我尝试在发布之前发送 10^6 个整数 (4 MiB),速度也一样快。然而,10^7 整数将导致程序崩溃(段错误)。
A.f90
program performance_test
use iso_c_binding, only: C_CHAR, C_NULL_CHAR, C_INT, C_PTR, C_LOC
implicit none
! Interfaces that ensure type compatability between Fortran and C.
interface
subroutine client(ipaddr, portnum) bind(C, name="client")
use iso_c_binding, only: c_char, c_int
character(kind=c_char) :: ipaddr(*)
integer(kind=c_int), value :: portnum
end subroutine client
subroutine calc(indata, length) bind(C, name="calc")
use iso_c_binding, only: c_ptr, c_int
implicit none
integer(c_int), value :: length
type(c_ptr), value :: indata
end subroutine calc
end interface
! type declaration statements
integer(c_int), allocatable, target :: array(:)
type(c_ptr) :: cptr
integer portno, length, i
! executable statements
! Call client.c and connect to localhost on port number `portno'.
portno=55555
call client(C_CHAR_"localhost"//C_NULL_CHAR, portno)
! Put numbers in the array
length = 1000000
allocate(array(0:length))
cptr=c_loc(array(1))
do i=1, length
array(i) = 2
end do
! Call client.c and pass the query on towards calcs.f90.
call calc(cptr, length)
deallocate(array)
end program performance_test
客户端.c
/* The original code for this client can be found here:
* http://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/client.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
// Static variables
static int sockfd;
/* This function is called when a system call fails. It displays a message about
* the error on stderr and then aborts the program. */
void error(char *msg)
{
perror(msg);
exit(0);
}
/* Callable function from Fortran, used by calcf.f90, to connect to a server.
*/
int client(char *ipaddr, int in_portno)
{
int portno;
struct sockaddr_in serv_addr;
struct hostent *server;
portno = in_portno;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(ipaddr);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
memset(((char *) &serv_addr), 0, (sizeof(serv_addr)));
serv_addr.sin_family = AF_INET;
memcpy(((char *)server->h_addr),
((char *)&serv_addr.sin_addr.s_addr),
(server->h_length));
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
return 0;
}
/* Callable function from Fortran, used by calcf.f90, as a calculator.
* calc passes the query stored in buffer to server and returns the
* answer. */
int *calc(int *indata, int length)
{
int n;
n = write(sockfd, indata, sizeof(int)*length);
if (n < 0)
error("ERROR writing to socket");
n = read(sockfd, indata, sizeof(int)*length);
if (n < 0)
error("ERROR reading from socket");
return indata;
}
服务器.c
/* The original code for this server can be found here:
* http://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/server.c */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
/* This function is called when a system call fails. It displays a message about
* the error on stderr and then aborts the program. */
void error(char *msg)
{
perror(msg);
exit(1);
}
/* Callable function from Fortran, used by calcs.f90, to start a server that
* can recieve queries. */
int server(int in_portno)
{
int sockfd, newsockfd, portno, clilen;
struct sockaddr_in serv_addr, cli_addr; int n;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
memset(((char *) &serv_addr), 0, (sizeof(serv_addr)));
portno = in_portno;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
while(1)
{
int length = 1000000;
int indata[length];
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
// Here comes the query from client.c
n = read(newsockfd, indata, sizeof(int)*length);
if (n < 0) error("ERROR reading from socket");
square(indata);
// write returns the data to the client
n = write(newsockfd, indata, sizeof(int)*length);
if (n < 0) error("ERROR writing to socket");
}
return 0;
}
B.f90
program calculator_server
! Calculator at the server side of the client/server calculator
! Responsible for starting up the server server.c
use iso_c_binding, only: C_CHAR, C_NULL_CHAR, C_INT, C_PTR
implicit none
! type declaration statements
integer calc, ans, portnum, calculate
! Interface that ensures type compatibility between Fortran and C
interface
subroutine server(portnum) bind(C, name="server")
use iso_c_binding, only: c_int
integer(kind=c_int), value :: portnum
end subroutine server
subroutine square(intarray) bind(C, name="square")
use iso_c_binding
type(c_ptr), value :: intarray
end subroutine square
end interface
! Start the server with portnumber
portnum = 55555
call server(portnum)
end program calculator_server
! **********************************************************************
subroutine square(cptr) bind(C, name="square")
use iso_c_binding
implicit none
! Variable declarations
type(c_ptr) :: cptr
integer*8 :: iptr
integer :: length, i
integer pointee(1000000)
pointer(iptr, pointee)
iptr = loc(cptr)
length = 1000000
! Execution
do i = 1, length
pointee(i)= pointee(i)**2
end do
end subroutine square
我的问题很简单,如果我遗漏了什么。自然地,我在程序的各个阶段打印了数据,以确保它确实被传递、平方和发回,所以程序执行它应该执行的操作。但是,我无法理解数据量无关紧要。我目前无法在两台不同的机器上尝试该程序,否则我也会那样做。
非常感谢任何关于可能导致此行为的想法。
最佳答案
至少存在一个问题:read()
返回的数据可能少于请求的数据。同样,send()
可能不会发送所有数据。以下列方式插入一对 printf()
到 server.c
// Here comes the query from client.c
n = read(newsockfd, indata, sizeof(int)*length);
if (n < 0) error("ERROR reading from socket");
printf("received %d, expected %lu\n", n, sizeof(int)*length);
square(indata);
// write returns the data to the client
n = write(newsockfd, indata, sizeof(int)*length);
printf("sent %d out of %lu\n", n, sizeof(int)*length);
执行时打印出来
received 43690, expected 4000000
sent 2539008 out of 4000000
因此只收到了预期数据的 1/90。
关于c - 测试 Fortran IPC : Sending 4 MiB of data using TCP/IP is equally fast as sending 100 B,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38054685/
在 Sitecore 中,我尝试在线路管理器中创建分段列表。但是,当我选择条件时,我对“等于”、“不区分大小写等于”和“不不区分大小写等于”感到非常困惑? 谁能给我解释一下其中的区别吗? 谢谢! 最佳
基本上,我想知道在这种情况下我是否应该听 ReSharper... 您认为与字符进行比较应该使用 Char.Equals(char),因为它可以避免拆箱,但 Resharper 建议使用 Object
假设 equals() 是可传递的;我知道如果 x 和 y 有平等的双边协议(protocol),那么其中一个,比如 y,不会单独与第三类 z 签订协议(protocol)。 但是如果我们遇到 x.e
我是 Haskell 新手,正在阅读: http://www.seas.upenn.edu/~cis194/spring13/lectures/01-intro.html 它指出“在 Haskell
阅读有关 C# 中的字符串比较的文章,我发现有很多方法可以比较 2 个字符串以查看它们是否相等。 我习惯了来自 C++ 的 == 但我了解到,如果你将一个对象与一个字符串进行比较,那么 == 默认为引
我有一个 Point 类和一个 MinesweeperSquare 类,后者是前者的子类。如果我重写后者的 equals 方法,就像这样: if (!(obj instanceof Minesweep
我想知道,如果我们有 if-else 条件,那么检查什么在计算上更有效:使用等于运算符或不等于给运营商?有什么区别吗? 例如,以下哪一项在计算上是高效的,下面的两种情况都会做同样的事情,但哪一种更好(
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
某些框架(例如 guice )在某些情况下需要创建 注解接口(interface)的实现类 . 好像有一个区别 Annotation.equals(Object) 之间和 Object.equals(
从三个变量开始,都是System.DateTime。 a: 10/2/2009 2:30:00 PM b: 10/2/2009 2:30:00 PM c: 10/2/2009 2:30:00 PM 相
我实现了一个 PagedModel 类来包装 IEnumerable,为我的 MVC 应用程序中的网格提供分页数据。我使用 Resharper 自动生成的 Equality 代码告诉它检查数据、总行数
正如问题所述。理想情况下,答案应该是 false,因为它将使用 Object#equal,这只是引用比较。 String cat = new String("cat"); String
我想知道以下两个选项中哪一个在速度方面最有效。它们之间可能只有很小的区别(或者根本没有区别?)但是由于我每天使用该代码片段 30 次,所以我想知道这里的“最佳实践”是什么 :) 选项 1: if (s
我有一个以年龄和姓名作为实例成员的基类,以及带有奖金的派生类。我在派生类中重写 equals 。我知道 Java 中只有一个基类时 equals 是如何工作的。但我无法理解继承的情况下它是如何工作的。
==之间的区别和 ===是前者仅检查值(1 == "1" 将返回 true),后者是否检查值并另外检查类型(1 === "1" 将返回 false,因为 number 不是字符串)。 比较对象意味着比
这是一个理论问题。我有一个我自己设计的对象,其中包含一堆变量、方法等。我覆盖了 toString 方法,主要用于记录目的,以返回变量的值。在我看来,比较此对象实例的最简单和最直接的方法是比较从 toS
我是 Java 编程的初学者。目前我正在 this 阅读关于继承和 equals 方法的内容。页。到目前为止,我理解解释: Compare the classes of this and otherO
当 IntelliJ 建议我更正以下内容时,我正在编写代码: objectOne.equals(objectTwo); 告诉我方法调用 equals 可能会产生旧的 java.lang.NullPoi
我尝试创建一个允许在 Java 中使用类似元组的结构的元组类。元组中两个元素的一般类型分别是 X 和 Y。我尝试为此类覆盖正确的等号。 事情是,我知道 Object.equals 属于默认值,它仍然根
可以用和比较字符串类似的方式来比较序列。如果两个序列的长度相同,并且对应元素都相等,equal() 算法会返回 true。有 4 个版本的 equal() 算法,其中两个用 == 运算符来比较元素,另
我是一名优秀的程序员,十分优秀!