1

私は遺伝的アルゴリズムを実装しています。クリーチャーは、入力と出力として3つのポインターを持つ関数です。すべての形式は次のとおりです。

// No need for global variables

void _start (float *i, float *o, float *m)
{
    ...
    ...
    ...
}

クリーチャーは数千で非常に小さいはずなので、共有オブジェクトを使用せずに、生のコードをロードして実行することにしました。

生き物はコンパイルされます

gcc -O3 -c code.c

次に、このように関数のコードを取得します

objcopy -O binary --only-section=.text code.o rawcode

次に、コードをメモリにロードして実行します

((void(*)(void*,void*,void*)) loaded_code) (i, o, m);

これは、ソースコードに浮動小数点リテラルがなくなるまで機能します。たとえば、次のコードです。

void _start (int *i, int *o, int *m)
{
    i[0] = m[0] + m[1];
}

Compilatedは、次の作業コードを生成します。

gcc -O3 -c code.c
objdump -d code.o

code.o:     formato del file elf64-x86-64


Disassemblamento della sezione .text:

0000000000000000 <_start>:
   0:   f3 0f 10 02             movss  (%rdx),%xmm0
   4:   f3 0f 58 42 04          addss  0x4(%rdx),%xmm0
   9:   f3 0f 11 07             movss  %xmm0,(%rdi)
   d:   c3                      retq   

しかし、浮動小数点リテラルを次のように持つ関数:

void _start (float *i, float *o, float *m)
{
    i[0] = m[0] + 3.0f;
}

実行しても正しい結果が得られないコードを生成します

gcc -O3 -c code.c
objdump -d code.o

code.o:     formato del file elf64-x86-64


Disassemblamento della sezione .text:

0000000000000000 <_start>:
   0:   f3 0f 10 05 00 00 00    movss  0x0(%rip),%xmm0        # 8 <_start+0x8>
   7:   00 
   8:   f3 0f 58 02             addss  (%rdx),%xmm0
   c:   f3 0f 11 07             movss  %xmm0,(%rdi)
  10:   c3                      retq

そして、これは、 %ripを使用して命令が生成されるたびに発生します。このコードを生成しないようにgccを設定するにはどうすればよいですか?理論的には、浮動小数点定数を挿入するには、ここで行うことができますか?

この問題を回避するための提案はありますか?

4

1 に答える 1

0

コンパイラは、.rodataコピーさえしないセクションに定数を配置するため、単なる再配置の問題ではありません。objcopy次のように、代わりに、必要に応じてコードをマージして再配置するカスタム リンカー スクリプトを使用できます。

OUTPUT_FORMAT(binary)

SECTIONS
{
    merged : {
        *(.text)
        *(.rodata)
    } = 0x90

    /DISCARD/ : {
        *(*) /* discard everything else */
    }
}

共有オブジェクトを回避したい理由がわからない場合は、それが最も簡単な解決策です。それらだけdlopenで、詳細を気にする必要はありません。

于 2013-03-04T22:54:29.647 に答える