zero-copy

場(chǎng)景: 從本地磁盤讀取數(shù)據(jù),然后將這些數(shù)據(jù)通過socket發(fā)送到遠(yuǎn)端。

read(file, user_buf,? len); // read data from disk

write(socket, tmp_buf, len); // write data into NIC.

完整過程如下:

1: 將文件從磁盤讀到kernel

2: 將kernel中的數(shù)據(jù)copy到user_buffer? ?// read done.

3:? ?將user_buffer中數(shù)據(jù)復(fù)制到kernel

4: 將kernel中數(shù)據(jù)復(fù)制到NIC。

上述過程4 次 context switch, 4次copy。

引入zero-copy 技術(shù)

1: 將文件從磁盤讀到kernel。

2: 將kernel中的數(shù)據(jù)發(fā)到NIC。

上述過程1次context switch, 2次copy。

system interface

ssize_t sendfile( int?out_fd, int?in_fd, off_t *offset,? size_t?count?);

sendfile() copies data between one file descriptor and another. Because this copying is done within the kernel,?sendfile() is more efficient than the combination of?read?and?write?, which would require transferring data to and from user space.

in_fd :?should be a file descriptor opened for reading and?out_fd?should be a descriptor opened for writing. If?offset?is not NULL, then it points to a variable holding the file offset from which?sendfile() will start reading data from?in_fd. When?sendfile() returns, this variable will be set to the offset of the byte following the last byte that was read. If?offset?is not NULL, then?sendfile() does not modify the file offset of?in_fd; otherwise the file offset is adjusted to reflect the number of bytes read fromi n_fd. If?offset?is NULL, then data will be read from?in_fd?starting at the file offset, and the file offset will be updated by the call.count?is the number of bytes to copy between the file descriptors. The?in_fd?argument must correspond to a file which supports?mmap(2)-like operations (i.e., it cannot be a socket). In Linux kernels before 2.6.33,out_fd?must refer to a socket. Since Linux 2.6.33 it can be any file. If it is a regular file, then?sendfile() changes the file offset appropriately.

=============================================================================

場(chǎng)景:

對(duì)于一個(gè)流對(duì)象,當(dāng)從這個(gè)流對(duì)象讀取數(shù)據(jù)的時(shí)候,需要傳遞給流對(duì)象一個(gè)buffer, 因此,此處存在一次memory copy。例如:在asio中socket的讀寫操作。

ZeroCopyInputStream?and?ZeroCopyOutputStream?interfaces, which represent abstract I/O streams to and from which protocol buffers can be read and written.

For a few simple implementations of these interfaces, see?zero_copy_stream_impl.h.

These interfaces are different from classic I/O streams in that they try to minimize the amount of data copying that needs to be done. To accomplish this, responsibility for allocating buffers is moved to the stream object, rather than being the responsibility of the caller. So, the stream can return a buffer which actually points directly into the final data structure where the bytes are to be stored, and the caller can interact directly with that buffer, eliminating an intermediate copy operation.

As an example, consider the common case in which you are reading bytes from an array that is already in memory (or perhaps an mmap()ed file). With classic I/O streams, you would do something like:

char buffer[BUFFER_SIZE];

input->Read(buffer, BUFFER_SIZE);

DoSomething(buffer, BUFFER_SIZE);

Then, the stream basically just calls memcpy() to copy the data from the array into your buffer. With a?ZeroCopyInputStream, you would do this instead:

const void* buffer;?

int size;

input->Next(&buffer, &size);

DoSomething(buffer, size);

Here, no copy is performed. The input stream returns a pointer directly into the backing array, and the caller ends up reading directly from it.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 段家軍已經(jīng)進(jìn)軍閑魚,繼糗百、網(wǎng)易、騰訊、淘寶買家秀之后,閑魚也被段家軍攻陷……有例為證,目前閑魚段家軍的暗號(hào)是:我...
    霖少爺閱讀 22,233評(píng)論 0 0
  • 我害怕,害怕死亡,一切消失,害怕,真的很害怕,你離開了,只有自己害怕。
    寫給我的她閱讀 79評(píng)論 0 0
  • 今天在朋友圈近乎刷屏的轉(zhuǎn)帖,是一位退休老教授對(duì)于自家小孫子在經(jīng)歷了雞血的備考民小之路完結(jié)時(shí)的一些感慨,思考以及無奈...
    11egnaw閱讀 253評(píng)論 0 0
  • 這兩天高考成績(jī)的陸續(xù)公布,也讓我小激動(dòng)了一下,雖然我已經(jīng)是一名大四的老學(xué)長了,但我還有一年才能畢業(yè),因?yàn)槲业?..
    GabrielMorningS閱讀 228評(píng)論 0 1